Entradas etiquetadas como ‘visual basic’

Utilizando el algoritmo Chudnovsky y Visual Basic para calcular los catorce primeros dígitos decimales de Pi sin despeinarse (y otros chismes y cotilleos varios)

Pi

Pi

Geométricamente hablando, π (pi) es la relación entre la longitud de una circunferencia y su diámetro; matemáticamente hablando, π es una constante con un valor que, generalmente, se redondea a 3,14 (en el colegio) o a 3,14159 (en la universidad). Conocido universalmente como 3,1416, π ha sido aproximado a lo largo de la historia hasta una exactitud de 5 billones de decimales, esto hace bien poquito. Y es que los matemáticos y los informáticos no tienen otra cosa que hacer en este mundo que perder el tiempo intentando encontrar un decimal nuevo para hacerse famosos y salir en el Muy Interesante y en la Wikipedia. Como si no supieran que esta carrera no tiene fin, y que pasado mañana saldrá a la palestra un chino mandarino o un japonés loco que encontrará el decimal número 6 billones; como si lo estuviera viendo.

Para los estudiantes del bachillerato actual diremos que π señala las veces en que el diámetro de un círculo cabe en su circunferencia. Ahora sí, ¿verdad? Hacemos un redondel con una cuerda y la estiramos en el suelo. Luego marcamos los diámetros sobre la cuerda y comprobamos que nos caben 3 y un poquito más. Eso es π. El siguiente GIF animado es totalmente esclarecedor.

Explicación gráfica de Pi muy sencilla de entender

Explicación gráfica de Pi muy sencilla de entender

En fin, nos unimos al carro de aproximaciones de π, pero no para intentar descubrir el decimal seiscientos trillones, sino para conocer el algoritmo Chudnovsky, uno de los más modernos métodos de calcular decimales de π. Algoritmos para este menester ha habido infinidad de ellos desde que el mundo es mundo, empezando por el de Arquímedes y pasando por los de Euler, Newton o Gauss (sí, el de las campanas).

El algoritmo Chudnovsky, descubierto por los hermanos David y Gregory Chudnovsky, matemáticos ucranianos, parece ser el más empleado en los cálculos de alta precisión de dígitos de π a comienzos de este siglo XXI en el que nos encontramos. Se fundamenta en una fórmula del hindú Ramanujan e implementa una serie de convergencia rápida siguiendo una serie hipergeométrica. Su fórmula es la siguiente:

Algoritmo matemático Chudnovsky

Algoritmo matemático Chudnovsky

Como se puede comprobar, no es más que un sumatorio sobre k desde 0 hasta infinito (∞), donde se hacen una barbaridad de operaciones en función de k en cada iteración. Cada término de esta fórmula añade 14 decimales exactos al valor calculado de π; k es una proporción entre la precisión en decimales que necesitemos calcular y el valor límite de 14. Es una fórmula incluida en el famoso software Mathematica, de uso común en el ámbito científico.

Lo que se detalla a continuación es un pequeño código en Visual Basic que nos permite extraer el valor exacto de π con sus catorce primeros decimales haciendo uso de la fórmula de los hermanos Chudnovsky. Es muy sencillo de entender, ya que sólo sigue paso a paso el algoritmo. Destacar únicamente la función auxiliar Factorial para calcular los factoriales requeridos.

Private Sub Chudnovsky()
    Dim k As Long
    Dim numeroPI As Double
    Dim Numerador As Double, Denominador As Double
    Dim Precision As Double, Limite As Double

    k = 0: numeroPI = 0
    Precision = 14
    Limite = (Precision + 3) / 14

    Do While k < Limite
        Numerador = 0
        Denominador = 0

        Numerador = ((-1) ^ k) * Factorial(6 * k) * (13591409 + (545140134 * k))
        Denominador = Factorial(3 * k) * (Factorial(k) ^ 3) * (640320 ^ ((3 * k) + (3 / 2)))

        numeroPI = numeroPI + (Numerador / Denominador)

        k = k + 1
    Loop

    numeroPI = 12 * numeroPI
    numeroPI = 1 / numeroPI

    Debug.Print FormatNumber(numeroPI, 14)
End Sub

Private Function Factorial(numFactorial As Long) As Double
    Dim i As Long, TempFactorial As Double
    TempFactorial = 1

    For i = 1 To numFactorial
        TempFactorial = TempFactorial * i
    Next i

    Factorial = TempFactorial
End Function

Que nadie intente calcular más de catorce decimales porque precisamente ese es el límite de las variables de doble precisión en Visual Basic. Eso sí, se puede extraer un número inferior alterando el valor de la variable Precision.

Los hermanos Chudnovsky, actualmente, residen en Estados Unidos y, además de por su habilidad en la construcción de supercomputadores caseros, son conocidos por la estrecha relación laboral que ambos mantienen, llegando a definirse ellos mismos como “un único matemático ocupando dos cuerpos”. Esta colaboración también está marcada, en cierta medida, por la enfermedad de tipo muscular que sufre Gregory, que lo hace en ocasiones dependiente de su hermano David. De este último se ha llegado a decir que es el mejor matemático vivo de la historia.

Los cerebritos calculines continuarán su gesta de intentar llegar al final del número π, hasta el último decimal que lo convierta en un número irracional transcendente de valor concreto. O quizás tengan razón aquellos que aseguran que los decimales de π no se acabarán nunca, y que dicen que es un número tan complejamente apasionante que, por ejemplo, todos los números de teléfono del mundo se pueden encontrar escondidos en la secuencia decimal de π, porque sus dígitos parecen estar repartidos aleatoriamente y no construidos de una forma particular (encontrándose entre sus infinitos guarismos cualquier secuencia posible). O es probable que todos ellos tengan razón y ninguno de ellos la tenga, aunque seguramente la longitud de π acabará siendo bastante mayor que el título de este post (aunque parezca mentira).

Lo que está claro es que π es, para muchos, un número mágico donde buscar mensajes ocultos, y para todo el mundo un valor importantísimo que permite construir carreteras y barcos, entre otras muchas cosas. Su número de decimales importa poco a niveles prácticos hoy en día, porque sería una locura realizar cálculos con tal nivel de exactitud, además de una estupidez supina. Pero, por lo menos, vamos observando nuestra amplia evolución desde hace un par de miles de años, cuando se deducía de la mismísima Biblia que el valor de π era simplemente igual a 3; en Primera de Reyes, 7-23, dice literalmente:

Hizo fundir asimismo un mar de diez codos de un lado al otro, perfectamente redondo; su altura era de cinco codos, y lo ceñía alrededor un cordón de treinta codos.

Por último, y ya que estamos en ello, recomendar desde aquí la película “Pi, fe en el caos“, una obra de arte geek y profundamente paranoica y demente, pero que todo buen friqui tecnológico debe visionar. Especial atención a sus múltiples fallos, comenzando desde el principio por el más garrafal de todos.


EDITANDO ANDO (17/09/2010): Se acaba de superar del récord de decimales de π calculados mencionado en esta entrada. Además ha sido a lo bestia, porque de 5 billones hemos pasado a 2.000 billones; casi na. El mérito es para un currela de Yahoo que se ha aprovechado de la infraestructura tecnológica de su empresa para tal menester. Así cualquiera.

Cómo escribir código VB .NET puro

Habrás leído mil veces en otras tantas páginas web que a la hora de diseñar tu aplicación en Visual Basic .NET, lo ideal es olvidarse del antiguo Visual y aprender a generar código puro para el Framework .NET. El problema es que si estás en proceso de adaptación a la nueva plataforma, es más que probable que no sepas cuando estás utilizando una instrucción que viene de antiguo y cuando no.

El quid de la cuestión está en el espacio de nombres Microsoft.VisualBasic, que Visual Studio importa por defecto a tus nuevos proyectos debido a esa sempiterna manía de Microsoft de lo que denominan “compatibilidad hacia atrás”, y que a veces es tan bueno y otras veces no tanto. Al principio esto puede parecer útil en un proceso de migración, pero en última instancia te va a resultar contraproducente en tu nuevo proceso de adaptación y aprendizaje.

Vale, y entonces ¿cómo lo hago? Muy fácil, chaval. Te voy a contar un truco de cosecha propia que reducirá tu curva de aprendizaje sustancialmente.

¡Venga, venga, dime! Ya voy, no te aceleres.

Cuando escribas código procura utilizar siempre clases nativas de .NET. Yo no te voy a contar qué se puede y qué no se puede usar, lo puedes encontrar en multitud de sitios web y en la propia documentación de migración de Microsoft. Al terminar el proceso de desarrollo, vete a las propiedades de la aplicación, a la pestaña Referencias, y desactiva la casilla de verificación del espacio de nombres Microsoft.VisualBasic. En este momento, todo tu código se llenará de preciosos errores allí donde haya un pedazo antiguo y no soportado en .NET de forma nativa.

Ahora ya puedes ir depurando cada error hasta que Visual Studio te vuelva a dejar compilar tu bonito assembly libre de código obsoleto.

¡Chupao!

AVBAX es AJAX, pero raro (y III)

Bueno. Por fin vamos a terminar esta serie explicando la mejor utilidad que se le puede dar al AVBAX, esto es, el acceso asíncrono a un archivo XML, que para eso se inventó todo este tinglado; vamos, digo yo…

Supongamos un archivo XML (al que llamaremos archivoxml.xml para seguir con la originalidad) que guarda grupos de música y álbumes publicados y que contenga las siguientes líneas

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  <xml>
    <Album ref="CD142" categoria="Pop">
      <titulo>Guapa</titulo>
      <artista>La oreja de Van Gogh</artista>
    </Album>
    <Album ref="CD720" categoria="Rock">
      <titulo>Zapatillas</titulo>
      <artista>El canto del loco</artista>
    </Album>
    <Album ref="CD024" categoria="Rap">
      <titulo>Vivir para contarlo</titulo>
      <artista>Violadores del verso</artista>
    </Album>
</xml>

Veamos primero el procedimiento Sub:

Sub ObtenerDatos()
  AVBAX.Open "GET", "archivoxml.xml"
  AVBAX.onreadystatechange = Getref("ComprobarEstadoYLeer")
  AVBAX.Send()
End Sub

Y ahora la función que recoge los datos (y controla el estado de la transacción):

Function ComprobarEstadoYLeer()
  If (AVBAX.readyState = 4) Then
    Set XMLDoc = AVBAX.responseXML.documentElement
    Set NodosXML = XMLDoc.ChildNodes
    For Each Elemento In NodosXML
      miCapaContenido.innerHtml = miCapaContenido. _
      innerHtml & "<BR>" & Elemento.ChildNodes(0). _
      NodeName & ": " & Elemento.ChildNodes(0). _
      Text & " // " & Elemento.ChildNodes(1). _
      NodeName & ": " & Elemento.ChildNodes(1).Text
    Next
    miCapaContenido.innerHtml = miCapaContenido. _
    innerHtml & "<BR><BR>" & _
    "Número de registros: " & NodosXML.Length
    Set AVBAX=Nothing
  End If
End Function

En este caso deberemos cambiar la propiedad responseText por responseXML, haciendo así que se interprete el archivo con su formato original, y no como un simple fichero de texto. Nos creamos una variable que guardará el objeto de elemento del documento con la propiedad documentElement de responseXML. Así pues, en XMLDoc se almacena el objeto de documento completo.

Para poder acceder a los distintos elementos internos del XML (o nodos para los puristas) nos servimos de otra variable para almacenarlos; esta variable será NodosXML que hace uso de la colección ChildNodes del objeto XMLDoc previamente declarado. Y ahora recorremos todos los nodos con un bucle For... Next.

Mientras leemos los nodos extraemos el nombre de cada subnodo (o nodo hijo con respecto al anterior) con la propiedad NodeName y su contenido textual con la propiedad Text. Los índices 0 y 1 se refieren a cada uno de los subnodos dependientes del anterior (0 para <titulo> y 1 para <artista>).

Entiéndase bien. Los nodos hijos del documento XML (guardados en NodosXML) son los distintos <Album>. Ahora, los nodos hijos de NodosXML son los distintos artistas y títulos de discos.

Todo el resultado se almacena en el innerHtml de la capa (objeto DIV) llamada miCapaContenido.

Por último escribimos el número de registros con la propiedad Length del objeto guardado en NodosXML.

Disponemos de multitud de propiedades para sacarle jugo a este objeto, entre otras: FirstChild, NodeType, NodeValue, OwnerDocument o ParentNode. También métodos: AppendChild, CloneNode, HasChildNodes o RemoveChild. Pero esto ya corre de vuestra cuenta y de vuestras ganas de investigar. Ajo y agua.

AVBAX es AJAX, pero raro (II)

Pos vale. Pos malegro. Y además de poder leer un archivo de texto alojado en el servidor remoto, ¿pa’ que más me sirve esto?

No se me alteren, por Dios, no se me alteren. En este segundo post vamos a explicar cómo hacer peticiones GET y POST a una página web con paso de parámetros y todo. ¡Acérquense que estamos que lo regalamos! ¡A regolvé, a regolvé!

Efectivamente, con el objeto XMLHttpRequest también podemos capturar el resultado de la petición parametrizada que escupe un ASP, o un PHP, o cualquier otro, actuando contra una base de datos.

Para peticiones GET deberemos especificar los parámetros en la línea del Open así (por ejemplo):

VBAX.Open "GET", "index.html?parametro1=Hola&parametro2=" _
& Escape(Cadena2), True

Donde Cadena2 es una variable previamente definida y con valor asignado, y Escape es una función VBScript que codifica una cadena transformándola en válida para una transacción HTTP. Esta función debe utilizarse siempre, o casi siempre, para evitarnos problemas a la hora de realizar las peticiones. Ya sabéis, nos convierte los caracteres raros para una URL (como espacios, eñes, tildes y demás) en otros todavía más raros (como +, %F1, etcétera) pero comprensibles para el navegador. ¿Cuando hablarán derecho estos paratos?

Para peticiones POST la cosa cambia un poco. Los parámetros han de pasarse desde el método Send de la siguiente manera:

AVBAX.Open "POST", "index.html", True
AVBAX.Send("parametro1=Hola&parametro2=" & Escape(Cadena2))

Como se comentó en el anterior post, entre ambas líneas de código irá la que indica la función que recogerá los resultados (la del onreadystatechange).

AVBAX es AJAX, pero raro (I)

Uno que viene mamado del BASIC del Spectrum y aborrece todo lo que suene a Java y JavaScript, tuvo que aguzar el ingenio para no perder el tren AJAX sin necesidad de utilizar una sola llave de código ni un anodino masmás de esos (que vienen a ser el contador suma de toda la vida, vaya). Por ello, y tras horas de prueba-error, llegó a la conclusión de que había inventado el AVBAX, o lo que es lo mismo, el AJAX vía VBScript. Días más tarde descubrió que ya estaba inventado y que, incluso (¡será posible!), algún avezado programador chino, o japonés, o tailandés, o lo que sea, le había llamado también AVBAX. Snif, snif.

Autorías aparte, el asincronismo con VBScript y XML es AJAX variando el leguaje script, por lo que el objetivo final es el mismo y el resultado igualico igualico. Lo único que, como no tengo la menor intención de aprender más JavaScript del que ya sé, a mí me resulta más sencillo e intuitivo.

Intentemos arrojar un poco de luz sobre el tema de la apotema comenzando, en este primer post, con un ejemplo que accede a un simple archivo de texto plano.

Al igual que con JavaScript, el primer paso consiste en crear el objeto XMLHttpRequest para poder acceder de manera asíncrona a un documento XML. Esto lo hacemos de aquesta forma:

Dim AVBAX
Set AVBAX = CreateObject ("Msxml2.XMLHttp")

Lo siguiente es definir el procedimiento Sub para obtener los datos del archivo de texto al que, haciendo gala de gran originalidad e inventiva, llamaremos archivo.txt.

Sub ObtenerDatos ()
  Dim URL
  URL = "archivo.txt"
  AVBAX.Open "GET", URL, True
  AVBAX.onreadystatechange = Getref ("ComprobarEstadoYLeer")
  AVBAX.Send ()
End Sub

El método Open prepara una conexión HTTP a través del objeto XMLHttpRequest. El primer parámetro es el método de conexión (GET o POST); el segundo parámetro es la URL para la petición HTTP (en este caso un simple fichero textual alojado en el mismo directorio que el HTML); el tercero es un parámetro booleano que toma valor True para utilizar el método asíncrono y False para el método síncrono (valga este último palabro, inexistente para el DRAE).

Por su lado, la propiedad onreadystatechange asigna la función que se ejecutará cuando la propiedad readyState (ver más adelante) cambie de valor. En este caso asignamos una función que se llama ComprobarEstadoYLeer, que definiremos a continuación. Send envía los datos de la petición.

Por último, definimos la función que comprobará el estado de la solicitud y actuará en consecuencia.

Function ComprobarEstadoYLeer ()
  If (AVBAX.readyState = 4) Then
    miCapaContenido.innerHtml = AVBAX.responseText
    Set AVBAX = Nothing
  End If
End Function

readyState toma los siguientes valores:

0 – Sin inicializar.
1 – Abierto.
2 – Enviado.
3 – Recibiendo.
4 – A punto.

Nosotros sólo podemos acceder a la respuesta cuando readyState sea igual a 3 ó 4, de ahí la condicional.

responseText devuelve el texto del documento descargado en la petición y, con la propiedad innerHtml del objeto miCapaContenido (que es una capa u objeto DIV), escribimos el resultado en pantalla. Al final descargamos el objeto de la memoria.

Por último queda decir que en el evento onClick de un botón de comando, por ejemplo, haríamos la llamada al procedimiento Sub y listo, Calisto. Chupado. No me digas.

Por supuesto, todo el código antes expuesto habría de ir contenido entre las marcas de rigor.

Sigue teknoPLOF! vía…
 
Twitter
RSS
 
Publicidad