25 de junio de 2020

Equations system with a black rectangle in LaTeX

A friend sent me a file in LaTeX that she had received. When compiling it, one of the equations had a strange black rectangle:
The file was about 20 pages long. After minimizing and minimizing the file, I got this simplified version:

\documentclass[12pt]{article}

\usepackage[table]{xcolor}



\begin{document}

\centering


Some initial text.



\[

  \begin{array}{c}

    \rowcolor{red}

      1 + 2 = 3 \\

    \rowcolor{green}

      1 + 2 = 3 \\

    \rowcolor{blue}

  \end{array}

\]




Some random two pages of text here \\

just to make debugging difficult.



\[

  \left\{

    \begin{array}{rrrrrrr}

       2x &+& y &+& 4z &=& 0\\

        x &+& 6y &+& 7z &=& 0\\

    \end{array}

  \right.

\]



Some final text.



\end{document}


Can you spot the error? In case you can't mentally compile LaTeX, the result is:

Now, is it easier to find the error?

[spoiler alert]

Well, the problem is in the previous table, it has the declaration of the color of the “last” row that does not exist. In the original version, it was a commented row, making it more difficult to spot. Moreover, between one table and the equations system there were one or two pages, making it more difficult to see that the error was actually caused by something that was much earlier than the position where it appeared.
\[

  \begin{array}{c}

    \rowcolor{red}

      1 + 2 = 3 \\

    \rowcolor{green}

      1 + 2 = 3 \\

    \rowcolor{blue}    % <---- the error is here

  \end{array}

\]



The strangest thing is that you get a black rectangle instead of a blue rectangle. I suppose some flag is set that says that there is something interesting in the next cell, but  the color is reset and that is why it is black. I've been looking at the xcolor package code, but my LaTeX-Fu is not strong enough. (It is not even clear to me if this is classified as a bug or not.) And furthermore, there is a workaround that is not to write LaTex with errors.


Bonus: The error is in the first part, so with a trivial change in the second part we can get a matrix or table with a strange black cell.
\begin{center}

  \begin{tabular}{|c|c| c|}

     \hline

      a  &  b  &  c  \\

     \hline

     $1$ & $2$ & $3$ \\

     \hline

  \end{tabular}

\end{center}

Sistema de ecuaciones con un rectángulo negro en LaTeX

Una amiga me pasó un archivo en LaTeX que había recibido. Al compilarlo una de las ecuaciones tenía un extraño rectángulo negro:
El archivo tenía unas 20 páginas. Después de minimizar y minimizar el archivo, llegué a esta versión simplificada:
\documentclass[12pt]{article}

\usepackage[table]{xcolor}



\begin{document}

\centering


Some initial text.



\[

  \begin{array}{c}

    \rowcolor{red}

      1 + 2 = 3 \\

    \rowcolor{green}

      1 + 2 = 3 \\

    \rowcolor{blue}

  \end{array}

\]




Some random two pages of text here \\

just to make debugging difficult.



\[

  \left\{

    \begin{array}{rrrrrrr}

       2x &+& y &+& 4z &=& 0\\

        x &+& 6y &+& 7z &=& 0\\

    \end{array}

  \right.

\]



Some final text.



\end{document}


¿Podés encontrar el error? Por si no podés compilar LaTeX mentalmente, el resultado es:
¿Ahora es más fácil encontrar el error?

[spoiler alert]

Bueno, el problema está en la tabla anterior, tiene declarado el color de la “última” fila que no existe. En la versión original, era una fila comentada, lo que hacía que sea más difícil notarla. Es más, entre una tabla y el sistema de ecuaciones había una o dos páginas, por lo que era más difícil ver que el error en realidad era causado por algo que estaba mucho antes de la posición en la que se veía
\[

  \begin{array}{c}

    \rowcolor{red}

      1 + 2 = 3 \\

    \rowcolor{green}

      1 + 2 = 3 \\

    \rowcolor{blue}    % <---- the error is here

  \end{array}

\]



Lo más extraño es que aparece un rectángulo negro en vez de un rectángulo azul. Supongo que queda seteado un flag de que hay algo interesante en la próxima celda, pero el color se resetea y por eso es negro. Estuve viendo el código del paquete xcolor, pero mi LaTeX-Fu no es lo suficientemente fuerte. (Ni siquiera me queda claro si esto se clasifica como un bug o no.) Y además hay una solución que es no escribir LaTex con errores.


Bonus: El error está en la primera parte, así que con un cambio trivial en la segunda parte podemos obtener una matriz o una tabla con una extraña celda negra.
\begin{center}

  \begin{tabular}{|c|c| c|}

     \hline

      a  &  b  &  c  \\

     \hline

     $1$ & $2$ & $3$ \\

     \hline

  \end{tabular}

\end{center}

30 de abril de 2020

Coquitos for quarantine

We are still in quarantine, but we had a bit of grated coconut and we made coquitos:
  • 200g grated coconut
  • 200g sugar
  • 2 eggs
  • I have no idea how hot the oven was.
We shaped them by hand, so they got with some very nice burnt stripes on the sides.

Coquitos: Some are already missing in the photo

(We tried a second time, but the mixture was very dry and after cooking they crumbled. It is very strange. Maybe it depends on the humidity of the grated coconut?)

Coquitos para la cuarentena

Seguimos de cuarentena, pero teníamos un poco de coco rayado e hicimos coquitos:
  • 200g de coco rayado
  • 200g de azucar
  • 2 huevos
  • No tengo idea qué tan caliente estaba el horno.
Les dimos forma a mano, así que les quedaron a los costados unas rayas quemaditas muy simpáticas.

 Coquitos: En la foto ya faltan algunos

(Probamos una segunda vez, pero la mezcla quedó muy seca y después de cocinarlos se desmenuzaban. Es muy extraño. ¿Quizás dependa de la humedad del coco rayado?) 

30 de marzo de 2020

About the AR$5 bill in Argentina

[Quarantined]

[I should have written this a month ago, because with the Covid-19 quarantine the situation changed a lot, and most of this doesn't make sense now. Anyways, this seems to be a story that deserves to be told and I have some free time.] [We are fine for now. Thanks for asking.]

Once upon a time, during February ...

The effective exchange rate of the (US) dollar is approximately AR$80, so according to the estimate in the article on the AR$1 coin, the AR$2 coin should fall into disuse. (Surprisingly, it took less time than expected.)
This is not a strict rule, but it is a custom in Argentina. Recently (January-February), I was already seeing that we started to round the prices to pay to a multiple of AR$5. For example, if we must be pay AR$102, it was likely that no one would demand the AR$2 coin.


We had AR$5 bills and AR$5 coins in circulation, but the bills were old and they recently were taken out of circulation. They can be exchanged in a bank, but they cannot be used in a business.


The problem is that the amount of coins of AR$5 is approximately 1/4 or 1/5 of the amount of bills! So, when the AR$5 bills stop circulating, nobody had enough AR$5 coins.

If there are no coins ...

The solution is then to use the AR$2 coins and even rummage through the drawers and dust off the AR$1 coins that had already practically fallen into disuse. I think I have seen more coins of AR$1 in the last days (February) than in the last months. In general, when paying the coins are combined to form a multiple of AR$5 because many of the prices of discrete products are already rounded. (Although there are exceptions such as candies that are worth AR$3 and are a problem.)


My proposal (in February) is to stick with Superglue two coins of AR$2 and one coin of AR$1 and get a combo of AR$5. It would be much easier than searching and choosing the coins one by one (although perhaps illegal). However, after a few days, surely someone will replace the middle coin with a fake one to obtain a 40% profit.

[Current situation]

[Due to the current situation, we are trying to do only one or two weekly purchases at the supermarket. It is a large purchase and we pay with a credit card, so nobody cares if there are coins or not.]

Sobre el billete de AR$5 en Argentina

[En cuarentena]

[Debería haber escrito esto hace un mes, porque con lo de la cuarentena por el Covid-19 la situación cambió mucho, y la mayor parte de esto no tiene sentido ahora. Igualmente me parece una historia que merece ser contada y tengo algo de tiempo libre.] [Por ahora estamos bien. Gracias por preguntar.]

Érase una vez, durante el mes de febrero …

El cambio efectivo del (US)dólar está a aproximadamente AR$80, así que siguiendo las estimaciones del artículo sobre la moneda de AR$1, las monedas de AR$2 deberían caer en desuso. (Sorprendentemente tardó menos de lo esperado.)
Esta no es una regla estricta, si no que es una costumbre en Argentina. En el último tiempo (enero-febrero), ya estuve viendo que empezamos a redondear los precios a pagar a un múltiplo de AR$5. Por ejemplo, si había que pagar AR$102, era probable que nadie exigiera la moneda de AR$2.


Teníamos en circulación billetes de AR$5 y monedas de AR$5, pero los billetes estaban medio viejos y recientemente salieron de circulación. O sea que se los puede cambiar en un banco, pero no se los puede usar en un negocio.
¡El problema es que la cantidad de monedas de AR$5 es aproximadamente1/4 ó 1/5 de la cantidad de billetes! Entonces al dejar de circular los billetes de AR$5 nadie tiene suficientes monedas de AR$5.

Si no hay monedas …

La solución es entonces usar las monedas de AR$2 y hasta revolver los cajones y desempolvar las de AR$1 que ya habían caído prácticamente en desuso. Creo haber visto más monedas de AR$1 en los últimos días (de febrero) que en los últimos meses. En general, al pagar las monedas se combinan para formar un múltiplo de AR$5 porque muchos de los precios de productos discretos ya están redondeados. (Aunque hay excepciones como los caramelos que valen AR$3 y son un problema.)
 


Mi propuesta (en febrero) es entonces pegar con La Gotita dos monedas de AR$2 y una moneda de AR$1 y obtener un combo de AR$5. Sería mucho más cómodo que andar buscando y eligiendo las monedas de a una (aunque quizás ilegal). Sin embargo, a los dos días seguro aparece uno que reemplaza la moneda del medio por una trucha para obtener un 40% de ganancia.

[Situación actual]

[Por la situación actual, estamos tratando de hacer sólo una o dos compras semanales en el supermercado. Es una compra grande y la pagamos con tarjeta de crédito, así que a nadie le importa si hay o no hay monedas.]

4 de febrero de 2020

Quantumly Generated Random Bytes in Racket

Let’s get the bytes

Last week I read about the project Quantum RNG for OpenQu that is a “quantum random numbers as a service”. The idea is to use it to get some random numbers in Racket, using the net/hhp-client and json modules.

This function creates a bytestring of length n using the service.

#lang racket

(require net/http-client
         json)

(define (quantum-random-bytes n)
  (define-values (status headers content)
    (http-sendrecv "random.openqu.org"        
                   (string-append "/api/randint"
                                  "?size=" (number->string n)
                                  "&min=0"
                                  "&max=255")))
  (list->bytes (hash-ref (read-json content) 'result)))

(quantum-random-bytes 5) ; ==> #"\2\353<\223\346"
(quantum-random-bytes 5) ; ==> #"\240\200\242\364\25"
(quantum-random-bytes 5) ; ==> #"\201\370\367\32\25"

Other random-bytes functions

For comparison, we can use the crypto-random-bytes function and we also can write our own random-bytes function that uses the build-in pseudorandom number generator.

(require racket/random) ; for crypto-random-bytes
(define (random-bytes n)
  (list->bytes
   (for/list ([i (in-range n)])
    (random 256))))

(random-bytes 5)         ; ==> #"E\31\366\4\333"
(crypto-random-bytes 5)  ; ==> #"b\345\207\315\""
(quantum-random-bytes 5) ; ==> #"\30`\325\3377"

(require file/sha1) ; for bytes->hex-string

(bytes->hex-string (quantum-random-bytes 5)) ; ==> "00b7c4d6db"
(bytes->hex-string (crypto-random-bytes 5))  ; ==> "662b108fd2"
(bytes->hex-string (random-bytes 5))         ; ==> "da25419554"

As expected, the result of all of them look like similar random nonsense. But it looks nicer as hexadecimal random nonsense.

The first is deterministic, but it uses the initial time of the program as a seed, so you will get different results in each run. Its’s good enough to for a game or simulation, and you can use random-seed to get the same sequence.

The second use the operative system random number generator and is cryptographically secure. The operative system mix many sources of entropy, but all (most?) of them are classic source. (It’s like rolling a dice, it’s difficult to predict but it’s not truly random.)

The third uses a quantum system to produce the random numbers. These numbers are truly random (if quantum mechanics is correct). But remember that you can’t use them for a password and other security applications because the server owner may have a copy (or be lying and sending the digits ofpi). Or someone could be wiretapping your internet connection (this use http, not https!).

(Note that this are not qbits. The “q” part is killed in the generation, long before they are sent through the wire.)

I guess you can use it for a nice truly random quantum choice of numbers, like the starting position of a solitaire game. It’s “better” that just shuffling the cards, but probably undistinguishable for the player. For the secure version, you should buy the hardware version (and verify that it works as intended).

Testing the numbers

In a previous article, I used Random Sanity that is a service that does a minimal check of the random numbers. It may have false positives, and it may not detect fake random numbers, so do it’s only useful to detect very bad implementations of (pseudo) random numbers generators.

Using the functions defined in that article to contact the service, we get:

(test-random-bytes (random-bytes 64))         ; ==> #t ;probably
(test-random-bytes (crypto-random-bytes 64))  ; ==> #t
(test-random-bytes (quantum-random-bytes 64)) ; ==> #t
(with-random-seed 1234567890
  (test-random-bytes (random-bytes 64)))      ; ==> #f

The first is almost always true, but it may be false if we all keep trying and sending the numbers created by the pseudorandom number generator. Using the birthday paradox, with 38 persons starting the program in the same second, we have a 50% chance to get a collision. (Or melt the server, whatever happens first.) The last one is false because it is using a fixed seed, and I already tested it and the server detects the collision now.

Note that now that the bytes have been tested, they are even less secure because yet another person has a copy.

Some ideas to try

  • There is an API call to get some bytes in the base64 format. I tried to use it, but I get an error message. It may work later. It may be useful base64-decode.
  • Without any good reason I’m generating a random byte string instead of a single random number. With small modifications, it’s simple to make function that is a replacement of (random n). Note that the max value of the interval in the service may be included in the results, so remember to subtract 1 before sending the request. I don’t know how big can be max.
  • There is another API call to get floating point numbers, which can be used to write a function that is a replacement of (random). Just note that the roundtrip on the network may take longer than tolerable for an interactive program.

Bonus: Another similar service

While looking for more info I found a few similar services, but most of them require some kind of registration. One that is easy to use is the ANU Quantum Random Numbers Server. Let’s use it too:

(define (other-quantum-random-bytes n)
  (define-values (status headers content)
    (http-sendrecv "qrng.anu.edu.au"        
                   (string-append "/API/jsonI.php"
                                  "?length=" (number->string n)
                                  "&type=uint8")))
  (list->bytes (hash-ref (read-json content) 'data)))

(other-quantum-random-bytes 5) ; ==> #"\25\n1\236K"
(other-quantum-random-bytes 5) ; ==> #"\271\375'\272\205"
(other-quantum-random-bytes 5) ; ==> #"\23\362\324\271\\"
(bytes->hex-string (other-quantum-random-bytes 5)) ; ==> "9366b3f8d2"
(test-random-bytes (other-quantum-random-bytes 64)) ; ==> #t

The link to the API is difficult to find, but this server only support int8, int16 and bytes strings in some hexadecimal format. On the other hand, it supports https, but that part is left as an exercise for the reader.

Bytes aleatorios generados cuánticamente en Racket

Busquemos los bytes

La semana pasada leí sobre el proyecto QuantumRNG for OpenQu que se autodefine como “números cuánticos aleatorios como servicio”. La idea es usarlo para obtener algunos números aleatorios en Racket, usando los módulos net/http-client y json

Esta función crea una cadena de bytes de longitud n usando el servicio.

#lang racket

(require net/http-client
         json)

(define (quantum-random-bytes n)
  (define-values (status headers content)
    (http-sendrecv "random.openqu.org"        
                   (string-append "/api/randint"
                                  "?size=" (number->string n)
                                  "&min=0"
                                  "&max=255")))
  (list->bytes (hash-ref (read-json content) 'result)))

(quantum-random-bytes 5) ; ==> #"\2\353<\223\346"
(quantum-random-bytes 5) ; ==> #"\240\200\242\364\25"
(quantum-random-bytes 5) ; ==> #"\201\370\367\32\25"

Otras funciones como random-bytes

A modo de comparación, podemos usar la función crypto-random-bytes y también podemos escribir nuestra propia función random-bytes que usa el generador de números pseudoaleatorios incorporado.

(require racket/random) ; for crypto-random-bytes
(define (random-bytes n)
  (list->bytes
   (for/list ([i (in-range n)])
    (random 256))))

(random-bytes 5)         ; ==> #"E\31\366\4\333"
(crypto-random-bytes 5)  ; ==> #"b\345\207\315\""
(quantum-random-bytes 5) ; ==> #"\30`\325\3377"

(require file/sha1) ; for bytes->hex-string

(bytes->hex-string (quantum-random-bytes 5)) ; ==> "00b7c4d6db"
(bytes->hex-string (crypto-random-bytes 5))  ; ==> "662b108fd2"
(bytes->hex-string (random-bytes 5))         ; ==> "da25419554"

Como era de esperar, los resultados de todos ellos parecen cosas aleatorias similares sin sentido. Pero se ve más lindo verlo como cosas hexadecimales aleatorias sin sentido.

La primera es determinista, pero utiliza el tiempo de inicio del programa como semilla, por lo que se obtienen resultados diferentes en cada ejecución. Es lo suficientemente bueno como para un juego o simulación, y se puede usar random-seed para obtener la misma secuencia.

La segunda utiliza el generador de números aleatorios del sistema operativo y es criptográficamente segura. El sistema operativo combina muchas fuentes de entropía, pero todas (¿la mayoría?) son fuentes clásicas. (Es como tirar un dado, es difícil de predecir, pero no es realmente aleatorio.)

El tercero usa un sistema cuántico para producir los números aleatorios. Estos números son verdaderamente aleatorios (si la mecánica cuántica es correcta). Pero no es buena idea usarlos para una contraseña y otras aplicaciones de seguridad porque el dueño del servidor puede tener una copia (o estar mintiendo y enviando los dígitos de pi). O alguien podrían estar interceptando tu conexión a Internet (¡esto usa http, no https!).

(Notar que esto no son qbits. La “q” se elimina en la generación mucho antes de que se envíen a través del cable.)

Supongo que se puede usar para una buena elección de números aleatorios en forma cuántica, como la posición inicial de un juego de solitario. Es "mejor" que simplemente mezclar las cartas, pero probablemente sea indistinguible para el jugador. Para una versión segura, es necesario comprar la versión en hardware (y verificar que funciona según lo declarado).

Testeando los números

En un artículo anterior, usé Random Sanity que es un servicio que realiza una verificación mínima de los números aleatorios. Puede tener falsos positivos y puede que no detecte números aleatorios falsos, por lo que solo es útil para detectar implementaciones muy malas de generadores de números (pseudo) aleatorios.

Usando las funciones definidas en ese artículo para contactar este servicio, obtenemos:


(test-random-bytes (random-bytes 64))         ; ==> #t ;probably
(test-random-bytes (crypto-random-bytes 64))  ; ==> #t
(test-random-bytes (quantum-random-bytes 64)) ; ==> #t
(with-random-seed 1234567890
  (test-random-bytes (random-bytes 64)))      ; ==> #f

El primero en general es verdadero, pero puede ser falso si todos generamos y enviamos los números creados por el generador de números pseudoaleatorios. Usando la paradoja del cumpleaños, con 38 personas que comienzan el programa en el mismo segundo, tenemos un 50% de posibilidades de tener una colisión. (O que se derrita el servidor, lo que pase primero.) El último es falso porque está usando una semilla fija, y yo ya lo testeé y el servidor ahora detecta la colisión.

Notar que ahora que los bytes han sido testeados, son aún menos seguros porque otra persona más tiene una copia.

Algunas ideas para probar

  • Hay una llamada API para obtener algunos bytes en el formato base64. Probé usarla, pero recibo un mensaje de error. Es posible que funcione más adelante. Puede ser útil base64-decode.
  • Sin ninguna buena razón, estoy generando una cadena de bytes aleatoria en lugar de un único número aleatorio. Con algunas modificaciones es fácil hacer una función que reemplace a (random n). Notar que el valor max del intervalo en el servicio está incluido en los resultados, así que hay que restar 1 antes de enviar la solicitud. No se que tan grande puede ser max.
  • Hay otra llamada API para obtener números de coma flotante, que se puede usar para escribir una función que reemplace a (random). Pero es importante recordar que el viaje de ida y vuelta en la red puede llevar más tiempo del tolerable para un programa interactivo.

Bonus: Otro servicio similar en español

Mientras buscaba más información encontré varios servicios similares, pero la mayoría de ellos pedían algún tipo de registración. Uno que es fácil de usar es el ANU Quantum Random Numbers Server. Probémoslo también:

(define (other-quantum-random-bytes n)
  (define-values (status headers content)
    (http-sendrecv "qrng.anu.edu.au"        
                   (string-append "/API/jsonI.php"
                                  "?length=" (number->string n)
                                  "&type=uint8")))
  (list->bytes (hash-ref (read-json content) 'data)))

(other-quantum-random-bytes 5) ; ==> #"\25\n1\236K"
(other-quantum-random-bytes 5) ; ==> #"\271\375'\272\205"
(other-quantum-random-bytes 5) ; ==> #"\23\362\324\271\\"
(bytes->hex-string (other-quantum-random-bytes 5)) ; ==> "9366b3f8d2"
(test-random-bytes (other-quantum-random-bytes 64)) ; ==> #t

El link a la API es difícil de encontrar, pero este servidos solo soporta int8, int16 y cadenas de bits en algún tipo de formato hexadecimal. Por otro lado, soporta https, pero esta parte queda como ejercicio para el lector.