¿Podemos fiarnos de los textos escritos por matemáticos?

Hoy os traigo algo que aunque hace tiempo que se produjo no había aparecido todavía por aquí. Es la respuesta de Rubén, de Automatic Human Behaviour la entrada Sólo con el ordenador no es suficiente que escribí hace un tiempo. He tomado prestado el título original de su post y el texto íntegro del mismo (él me dio permiso vía mail para hacerlo). La url del artículo en su blog es esta.


¿Podemos fiarnos de los textos escritos por matemáticos?

El artículo de hoy pretende ser una respuesta al texto, ¿Podemos fiarnos de los cálculos efectuados con ordenador? escrito por Óscar Ciaurri y Juán Luis Varona y publicado en La Gaceta de la Real Sociedad Matemática Española. Existe una versión en pdf y Diamond, de Gaussianos, publicó una versión resumida en su blog.

Mi hipótesis de partida es que este texto -si bien siempre es útil detectar fallos y errores comunes para que otros no los cometan- esta basado, parcialmente, en falacias con respecto al funcionamiento de los ordenadores y, lo que es peor, de las matemáticas que se emplean dentro de ellos.

Mi objetivo no es rebatir el texto original desde un blog, si no dar al lector las herramientas para comprobar por si mismo algunas de las falacias que he comentado y, de paso, hacer un poco de divulgación científica, que nunca viene mal.

Para empezar, vamos a presentar un modelo teórico que aproxima bastante bien las capacidades y, sobre todo, las limitaciones de cálculo de un ordenador. Es la conocida como, máquina de Turing.
Esta máquina no es mas que un robot que es capaz de procesar una cinta de datos codificados como unos y ceros. En cada instante, el robot puede leer o modificar el dato que tiene en el cabezal. La decisión se basa en un programa que, junto con los datos que lee, van cambiando el estado interno del robot.

De este modelo teórico, vemos dos cosas que se aplican a todos los ordenadores:

1) Los ordenadores solo son capaces de procesar números. Cualquier cosa que queramos que procesen, la tendremos que transformar a 1s y 0s. Un sonido lo tendremos que transformar en una secuencia de números. Una imagen también pasa a ser una secuencia de números. El texto también son números. Un ordenador no sabe leer, solo sabe contar. Todas estas conversiones se basan en convenios que habremos de decidir de antemano.

2) Los ordenadores -al menos los de un solo núcleo- procesan la información de manera secuencial. Esto tiene una implicación muy importante a la hora de determinar la complejidad de un problema. Por ejemplo, si el ordenador tiene que encontrar el camino óptimo entre una serie de rutas, tendrá que recorrerlas todas antes de estar totalmente seguro de que la que decida sera la óptima.

En determinadas situaciones, y partiendo ciertas intuiciones o información previa podemos obtener soluciones más eficientemente. También se puede buscar una solución que no sea la óptima, pero que en la práctica sea lo suficientemente buena. Sin embargo, en un caso general, no se pueden asumir dichas simplificaciones.

En el peor de los casos, podemos encontrarnos con problemas totalmente irresolubles, como el problema de parada, es decir, saber si un programa (con bucles, saltos e interrupciones) se va a parar o por el contrario, quedaría atrapado en un bucle que se ejecuta continuamente (lo que se llama un bucle infinito). La única forma de saberlo, es ejecutando el programa entero, con lo que si el programa tiene un bucle infinito, el programa quedara atrapado y nunca nos dará la solución.

3) También existe limitaciones a nivel práctico. El robot de Turing puede estar trabajando por tiempo indefinido hasta resolver casi cualquier problema (como hemos dicho cualquiera que tenga solución, lo que se llama un problema decible). Sin embargo, en la práctica, existen muchos otros problemas que no se pueden resolver por un ordenador normal, ya que son problemas intratables. La wikipedia pone el ejemplo de los problemas con complejidad exponencial:

Para ver por qué las soluciones de tiempo exponencial no son útiles en la práctica, se puede considerar un problema que requiera 2n operaciones para su resolución (n es el tamaño de la fuente de información). Para una fuente de información relativamente pequeña, n=100, y asumiendo que una computadora puede llevar a cabo 1010 (10 giga) operaciones por segundo, una solución llevaría cerca de 4*1012 años para completarse, mucho más tiempo que la actual edad del universo.

4) Otra limitación técnica viene del hecho de que la memoria (el tamaño de la cinta), no es infinita. De hecho, para almacenar cualquier posible número, necesitaríamos una cadena arbitrariamente larga de 1s y 0s. Eso no solo aumenta el coste de memoria, si no también el coste computacional de procesar un único número. De este modo, se suele limitar el tamaño de los números a 8, 16, 32 o 64 bits. Puede parecer que 64 bits dan mucho juego (son 264 números), y de hecho, lo dan, pero recordemos que los números naturales son infinitos números. Y tan lejos del infinito esta un googol como el 1. Pero es que además, como vimos en otros articulos, los números reales son un infinito de segundo orden, es decir, en el intervalo que hay entre cada uno de los infinitos números enteros, hay infinitos números reales, cada uno con potencialmente infinitos decimales. ¿No parecen demasiados para representarlos con 264 números? Pues se hace, pero con el consiguiente error asociado que hay que tener en cuenta.

En resumen, hay muchos problemas que para nosotros son triviales, pero que para un ordenador como los que utilizamos habitualmente, son imposibles ya que: requieren un tiempo de cálculo enorme, requiere una cantidad de recursos impracticable o simplemente, no existe ninguna forma de que el ordenador obtenga un resultado.

Para terminar con los preliminares, quisiera añadir un pequeño trasfondo de lo que es la Ingeniería de Software.

El software ha de pensarse que es como un producto más. Por ejemplo, podemos compararlo con un coche.

A principios del siglo XX, los vehículos a motor estaban todavía en fase de desarrollo. Los pocos vehículos que circulaban por las carreteras tenían continuos fallos y taras. Era raro poder circular más de 10 kilómetros sin que se gripase el motor, se fundiese alguna lampara o se pinchase una rueda. El mundo tampoco estaba preparado para ellos, y parte de los problemas provenían de carencia de pavimento en las carretas, falta de señalización, etc.

Sin embargo, a pesar de los avances que se han dado a lo largo del siglo XX (de todos es sabido que la industria de la automoción es una de las que más dinero mueve a nivel mundial), solo recientemente se han creado e implantado extensivos controles de calidad y diseños exhaustivos que otorgan una gran calidad al producto final y una garantía de seguridad.

Se tardó un siglo en desarrollar e implantar toda esa tecnología.

Por otro lado, a pesar de los avances que ha sufrido el campo de la automoción, no le pedimos a un coche que vuele, por mucho que lo utilicemos para viajar, y volar sea una forma eficaz de hacerlo. Incluso si alguien utiliza un motor de coche para volar, no es la mejor forma de hacerlo. Es una falacia razonar que si un elemento se utiliza para un fin, ha sido diseñado para ese propósito.

Por ejemplo, por mucho que utilicemos los ordenadores para cálculo simbólico, el modelo de ordenador de von Neumann, que aun hoy utilizamos, se diseñó para calculo numérico. Y punto. Cualquier algoritmo que resuelva problemas s
imbólicos será porque primero los convierte a problemas numéricos.

La Informática como ciencia y como tecnología, es mucho mas joven que la automoción. Sin embargo, ya se están empezando a implantar controles de calidad dignos de las grandes compañías de vehículos. Casi desde el principio de la programación, han existido los betatester (gente que se dedica a probar y sacar los fallos de un programa al final de su desarrollo), se han desarrollado técnicas de métodos formales y análisis de software para reducir al mínimo los errores.

Sin embargo, siempre aparecen errores. Al igual que en los vehículos siguen apareciendo fallos de diseño (como el famoso Mercedes que hace pocos años tuvo que ser retirado del mercado porque en caso de accidente, el motor se incrustaba en el habitáculo de pasajeros). Por desgracia, el software es algo que se maneja jerárquicamente. Aunque no nos demos cuenta, en todo momento estamos ejecutando varias piezas de software (programas de trabajo, sistemas operativos, drivers, controladores…) que a su vez están basados en otras piezas de software (compiladores, interpretes…). Simplemente con que falle solo uno de esos elementos, el sistema falla. Y lo más probable es que, a fecha de hoy, alguna de esas piezas de software estén todavía hechas con métodos antiguos de programación y sin los controles de calidad que hoy se utilizan. ¿Alguien se atrevería a conducir en una autopista donde, al fallar cualquiera de los vehículos que van en ella, automáticamente fallaran todos? ¡Estaríamos arreglando pinchazos cada 100 metros!

Pero en todo este panorama, los programadores tenemos una ventaja que la automoción no tendrá nunca, los demostradores de teoremas. Un demostrador de teoremas es un programa que nos garantiza, matemáticamente, que nuestro trozo de código hace exactamente lo que queremos que haga. Es decir, nos garantiza que matemáticamente es correcto, perfecto. Por desgracia, los demostradores de teoremas todavía se encuentra en fase de investigación y sus capacidades, a día de hoy, son muy limitadas. Realmente, la dificultad de un demostrador de teoremas, deriva de que es un cálculo simbólico, no numérico.

Ahora, vayamos por partes a resolver algunos de los puntos que comentan los autores. Como he dicho antes, no es mi idea rebatir el texto completo, así que me centrare en algunos de los puntos que se resumen en el blog de Gaussianos.

1) Cálculo de limites:

Los autores denuncian que una función cuyo limite en determinado punto varia si el limite se toma “por arriba” o “por abajo” no es resuelto como tal por Mathematica, ya que si le damos a calcular el limite, sin definir por donde se mira, nos devuelve el valor por arriba y no nos avisa de que esta indefinido.

Solo hace falta ir a la documentación de Mathematica y leer:

The value of Sign[x] at x=0 is 0. [..] Its limit, however, is 1. The limit is by default taken from above.

Es decir, Mathematica sí que nos avisa de que va a coger el límite “por arriba”. En muchos otros ejemplos del articulo, la crítica es la misma: el programa no nos informa de lo que hace. Eso es totalmente falso, porque como lo hemos visto, si que informa, aunque en la documentación. Lógicamente, un software de esa magnitud no puede estar informando de cada acción que haga. ¿Se imaginan los lectores un navegador de internet que cada vez que pulsara en un link le saliese un mensaje:

“Acaba de pulsar un link. Esto le enviara a otra pagina y dejará atras la página que esta leyendo. ¿Desea continuar?”

Acabaríamos todos de los nervios. Lo primero de todo, antes de usar un software, antes de usar cualquier herramienta, es leerse el manual. Eso lo sabe cualquier técnico y debería saberlo cualquier usuario de software. De hecho, existe un programa que se diseñó para intentar informar al usuario bastante a menudo, a sabiendas de que no se leería la documentación por su cuenta. El programa era el asistente de la ayuda de Microsoft Office, más conocido como Clippo. El odio que suscitó es tal, que existen hasta videojuegos cuyo único objetivo es aniquilar el personaje animado de la forma mas cruel posible.

2) Gráficos ficticios:

Decir que en este caso, gran parte del error que se comete no es de los autores originales, si no del resumen de Gaussianos.

En este caso, los autores protestan porque el programa no representa bien según que gráficas, haciendo clara referencia, aunque no explícita, al teorema de Niquist-Shanon.

Para empezar, decir que un ordenador, jamas podrá dibujar una gráfica continua, ya que por definición, tiene infinitos puntos. Y como hemos visto, para un ordenador, infinito es 264. Un ordenador siempre es discreto. De todos modos, aunque la pudiese representar, nunca la podría sacar por pantalla, ya que siempre tendríamos la limitación de los píxeles, o en último término, del ojo humano.

Pero aun así, en este caso, los autores originales claramente comentan que el software Mathematica puede resolver este problema hasta cierto punto. Por la descripción que hacen de la método que usa Mathematica, se están refiriendo al potente algoritmo de bootstrapping. Este algoritmo, aunque fundamentado en una solida base matemática, se puede explicar de manera bastante sencilla: En caso de que las muestras que estemos tomando no sean suficientemente representativas, podemos usar las que tenemos para obtener información sobre la función y así tomar más muestras en determinadas zonas “de manera inteligente”. De este modo se consigue mejorar la calidad del resultado con menos coste añadido.

Por desgracia, el algoritmo de bootstrapping es un algoritmo con coste exponencial. Es decir, cuando aumentamos el número de dimensiones, el coste aumenta enormemente hasta hacerlo intratable, como veíamos antes. Lógicamente, cuando un usuario le da al botón para dibujar una función, no quiere que pasen años o siglos antes de poder verla. Es por ello, que Mathematica ha limitado el uso del bootstrapping a gráficas de una sola dimensión, donde el tiempo de cálculo, entra dentro de lo razonable. Este nimio detalle es contemplado en el articulo original, pero en el resumen de Gaussianos, inexplicablemente, se perdió.

3) Simplificar

Este punto y otros por el estilo donde se habla del cálculo simbólico directamente no tienen sentido. Todos los razonamientos se basan en la premisa de: “Dado que esas operaciones son triviales para cualquiera, también lo deberían ser para la máquina.”

Bien, y yo me pregunto: ¿Por qué? Hemos visto que hay muchos problemas que son triviales para nosotros y no para un ordenador. Otros son triviales para el ordenador y tremendamente complejos para nosotros. Simplemente funcionamos distinto. De hecho, cuando se crearon originalmente, se crearon con la idea de complementarnos, luego se especializaron en lo que se nos da mal a los humanos. Lógico, ¿no creen?

Además,
los autores de Mathematica, dado que el calculo simbólico es muy costoso y ha de probar muchos caminos y opciones, han optado por dar una solución práctica. Han cogido las operaciones más rápidas y que aparecen más frecuentemente a la hora de simplificar y las han incluido en una función. Esta función tiene la ventaja de ser muy rápida, pero no te garantiza un resultado satisfactorio. Luego existe otra función que tiene una biblioteca de operaciones mucho más extensa y por lo tanto da mejores resultados, pero más lento.

Es como cuando nos vamos a comprar un libro, que primero leemos el resumen, y aunque no nos garantiza que el libro sea bueno o malo, si que en algunos casos nos puede servir de ayuda.

Esto no es una solución matemática, ni tiene ninguna base teórica. Simplemente se ha hecho así por comodidad del usuario. Prueba primero la rápida, y si no funciona, siempre podrás probar la lenta, pero si te funciona, eso que te has quitado de encima. Tiene sentido, ¿no?

Pero no sabemos como han escogido los programadores que operaciones poner en la rápida y cuales no. Y no existe ninguna justificación matemática. Hacer suposiciones con la premisa: “esta operación es muy sencilla, debería ser resuelto por la función resumida” simplemente no tiene ni pies ni cabeza.

4) Fallos de código:

Esta parte es la única que no esta basada en falacias. Es normal que haya fallos en un código, al igual que es normal que haya fallos en cualquier producto. No es deseable, pero somos humanos. Me parece una labor encomiable que se busquen esos errores y se hagan públicos a una comunidad que usa ese software masivamente. Incluso la idea de anunciar los fallos de versiones antiguas, ya que mucha gente no actualizara su software a menudo, al ser software de pago.

Desconozco si Mathematica ofrece actualizaciones gratuitas de las correcciones de software, aunque muchos de los programas comerciales sí lo hagan. Normalmente, aunque no nos demos cuenta, cuando se compra un software, muchas veces se compra también el soporte adicional.

Por otro lado, lo que veo un error es escribir el texto a modo de denuncia en vez de simplemente informativo. De hecho, muchos de esos fallos que se comentan se han corregido en las últimas versiones, lo cual es loable y no denunciable. Además en vez de denunciarlo en una revista española que no leerán los programadores, se puede contactar con ellos. Es muy probable que corrijan los fallos en la próxima versión e incluso nos regalen alguna suscripción gratuita por haberlos encontrado.

En este punto, es admirable la labor de las comunidades de software libre, donde puedes informar del error, que normalmente es subsanado a las pocas horas y, al día siguiente, puedes descargarte el nuevo código perfectamente arreglado.

Mi conclusión es que sí podemos fiarnos de los cálculos de un ordenador, pero no podemos fiarnos de los usos y decisiones que tomemos a posteriori.

Nota: Como punto final, me gustaría comentar que no tengo ninguna implicación con Mathematica ni con la compañía que lo ha desarrollado. Simplemente ha sido la herramienta en la que estaba basada el texto original. Personalmente, y dado que mis aplicaciones van más orientadas al cálculo numérico, prefiero Matlab. Como alternativa de software libre y gratuita, existe Octave, que si bien tiene alguna capacidad reducida, es un serio competidor. También existen lenguajes de programación orientados al cálculo científico con excelentes bibliotecas de apoyo, como por ejemplo R (para cálculo estadístico) y Python con SciPy (más general).


Como habéis visto Rubén me dio la réplica con este artículo y, aunque con muchísimo retraso, quería ponerla aquí. Espero vuestros comentarios sobre el asunto, pero, por favor, con la mayor educación posible tanto para hacia Rubén como hacia mí. Aviso ésto porque sé que estos temas a veces se salen de madre y pueden llegar a límites que no estoy dispuesto a aceptar. De todas formas estoy seguro de que todos sabremos mantener la compostura.

Autor: ^DiAmOnD^

Miguel Ángel Morales Medina. Licenciado en Matemáticas y autor de Gaussianos y de El Aleph. Puedes seguirme en Twitter o indicar que te gusta mi página de Facebook.

11 Comentarios

  1. Muy interesante tanto el original, como el resumen como la réplica.

    Muchos de los “fallos” comentados los he “padecido” yo también; pero precisamente el viernes me di cuenta que en MATHEMATICA está mal la función “Parte Entera” en los negativos. Curioso.

    Publica una respuesta
  2. Sólo le he echado un vistazo general a la entrada y no he leído el artículo de Oscar Ciaurri y Juan Luis Varona (que ha sido profesor mío, por cierto), aunque haré las dos cosas con más tiempo, pero nada más empezar me ha venido a la mente un apunte de Ricardo Galli de hace casi un año con el que estoy totalmente de acuerdo.

    Publica una respuesta
  3. Hola Tito Eliatron, aunque hablo sin el software delante, en el mathematica lo que habitualmente conocemos como parte entera corresponde a la sentencia “Floor[.]”. La sentencia “IntegerPart[.]” simplemente trunca la parte decimal.

    Publica una respuesta
  4. Tomemos la calculadora científica que tenemos en el escritorio de nuestra computadora. Ahora ingresemos el número 123456789123456789123. Luego tildemos el botón Bin para que nos muestre su expresión en binario. Para finalizar tildemos el botón Dec con el propósito de retornar al número inicial expresado en base decimal. Nos mostrará un número distinto al original.

    Publica una respuesta
  5. El artículo original yo me lo tomé como una razonable advertencia de que cuando utilizamos ordenadores hay que ser precavidos con los resultados que obtenemos, dado que puede haber una serie de factores que alteran el resultado final:
    – errores hardware: acordaros del famoso bug FDIV de los primeros Pentium, descubierto por cierto por un matemático mientras evaluaba la constante de Brun, etc.
    – errores de software: bastante habituales, a veces muy difícil de detectar por cierto.
    – nuestra ignorancia: como en el caso del límite de Mathematica, no saber que por defecto toma el límite superior (¡buen apunte, Rubén!).
    – errores de redondeo y truncamiento: serán inevitables trabajando con ordenadores pero es un tema bien estudiado (análisis numérico) y con las técnicas adecuadas se pueden acotar de manera que en todo momento sepamos el grado de validez de un resultado (error máximo cometido).

    Estoy de acuerdo con el artículo pero también contiene una imprecisión: “para un ordenador, infinito es 2^{64}”: el trabajar con registros de hasta 64 bits no limita la precisión de los números que queremos representar, es la cantidad de memoria total disponible lo que lo limita. Es cierto que en casi todos los lenguajes de programación los tipos de datos primitivos tienen esta limitación pero hay métodos para poder manejar números enteros y decimales con la precisión que deseamos (clases BigInteger y BigDecimal en Java, por ejemplo).

    Publica una respuesta
  6. A riesgo de ser quisquilloso. Sólo quiero comentar que Rubén también cae en una falacia al decir que los modelos de cómputo (como la máquina de Turing) se pensaron para hacer cálculo numérico. En realidad la máquina de Turing es una máquina de cálculo simbólico, y la cinta acepta cualquier alfabeto (por definición finito), no sólo unos y ceros.

    Es más, originalmente Turing lo que trataba de dilucidar era si existía un algoritmo para decidir si una proposición en lógica de primer orden era teorema. Luego construyó la máquina de Turing para representar cualquier algoritmo y así demostrar que era imposible que existiera un algoritmo que decidiera aquello.

    La computadora actual aunque no es una máquina de Turing en forma, también hace cálculo simbólico, no sólo numérico. Los saltos condicionados se salen de lo meramente numérico para entrar a lo simbólico también.

    PD. La lógica de primer orden es por mucho, mucho más compleja que la simple lógica proposicional, o el álgebra booleana.

    Publica una respuesta
  7. “¿Podríamos fiarnos de los textos escritos por matemáticos?”
    Con respecto a esta frase podríamos reemplazar la palabra “matemáticos” por otra que designe a las personas con otra ocupación y estaríamos en una situación parecida. Un texto puede estar escrito por una autoridad en la materia, pero aún así no es imposible que contenga algún error. El principio de autoridad no vale para la ciencia. De allí se desprende la importancia de la revisión de todo trabajo intelectual.

    Publica una respuesta
  8. Hola, no me gusta el título del artículo da que pensar, los profanos en la materia deducirán que los matemáticos engañan a la gente, esto es tirar piedras sobre nuestro propio tejado.
    Lo de errores de cálculo con un ordenador no son errores (si las funciones estan bien implementadas), sólo son pérdidas grandes o pequeñas de precisión que se van acumulando y que se originan porque los ordenadores les cabe lo que les cabe, nosotros también los cometemos a mano y papel, no podemos escribir todas las cifras de un irracional en un papel, la solución es escribirlo todo de forma algebraica hasta el resultado final, si es posible. De todo esto hay ya una especialidad específica en la rama de las Matemáticas con sus respectivas asignaturas, así que no se a qué viene esto.
    Si hay programas que nos engañan y son de pago no los utilicéis, así de simple. Yo paso de pagar licencias abusivas o de piratearlas, con el software libre me sobra: Octave, qtoctave, maxima, wxmaxima, R, rkward, Geogebra, Scilab, Graphthing, etc. son los que utilizo; y obtengo lo que quiero. Además se apoyan muchas de ellas en librerías matemáticas que vienen de Fortran, lenguaje por excelencia para obtener resultados matemáticos.
    Además, en un pc los números se guardan en binario, así que números con 4 cifras decimales en base 10 pueden tener infinitas cifras binarias, así pues es forzoso tener que cortar por algún sitio. El PC sólo entiende binario y esa transformación de base 10 a binario puede suponer ya un costo de obtención de cálculos veraces.
    Para que el PC sea continuo en su almacenamiento y no discreto creo que queda mucho, para ello las memorias físicas deberían asemejarse a fractales, se que ya hay discos duros considerados como fractales, aunque no se si son de uso doméstico.
    En un texto que leí por ahí decía que en un buen laboratorio no utilizan los típicos pcs caseros, utilizan ordenadores muy potentes y con un uso exclusivo a una determinada tarea de cálculo. Supongo que esto es de gran interés en disciplinas tales como la Biomedicina.

    Publica una respuesta
  9. Cuando se hace un programa de computación es conveniente indicar al usuario el límite a partir del cual los resultados no son exactos, sino aproximados.

    Publica una respuesta
  10. Gracias a todos por los comentarios y a Diamond por publicar la replica.

    Asier: Es cierto lo que dices, pero dado que la memoria es finita, no resuelve el problema. 2^64 esta tan lejos del infinito como 2^64000 😉

    Damian: Buen apunte. Lo de simbólico es un abuso de nomenclatura que se suele cometer bastante en informática. Realmente el cálculo numérico, como bien dices, es un caso especial del cálculo simbólico. Realmente debería haber dicho analítico. De hecho, la máquina de Turing permitió demostrar que la demostración automática de teoremas es, en el mejor de los casos, NP-completo. Y muchas veces es indecible. Por eso usamos aproximaciones numéricas.

    Omar-P, Cristobal: El titulo del articulo no es más que una parodia del titulo original. Aunque me encanta que consideréis que da que pensar o que refleja el proceso de revisión. 😀

    Publica una respuesta

Trackbacks/Pingbacks

  1. Bitacoras.com - Información Bitacoras.com... Si lo deseas, puedes hacer click para valorar este post en Bitacoras.com. Gracias....

Puedes utilizar código LaTeX para insertar fórmulas en los comentarios. Sólo tienes que escribir
[latex]código-latex-que-quieras-insertar[/latex]
o
$latex código-latex-que-quieras-insertar$.

Si tienes alguna duda sobre cómo escribir algún símbolo puede ayudarte la Wikipedia.

Y si los símbolos < y > te dan problemas al escribir en LaTeX te recomiendo que uses los códigos html & lt; y & gt; (sin los espacios) respectivamente.

Envía un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *