Simulating Mouse Movement To Draw In Mypaint

Wouldn't it be nice if we can command where to move the mouse pointer and press buttons, and then use the functionality to draw in a painting program? We can do exactly that in systems running xorg display server, by using xdotool to simulate mouse and keyboard.

E.g. to draw a simple 5 petal rose, \(r = \cos \left(5 \theta\right)\),

from os import system
from math import sin, cos, pi

x, y = 1920, 1080
xh, yh = x/2, y/2
n = 1
system('sleep 2; xdotool mousemove '+str(xh+yh)+' '+str(yh))

for d in range(n*360+1):
    th = d*pi/180
    r = yh*cos(5*th)
    x, y = xh+r*cos(th), yh+r*sin(th)
    system('xdotool mousedown 1 mousemove '+str(x)+' '+str(y)+' mouseup 1')
    system('sleep 0.01')

Below is the result of running the script with mypaint opened in fullscreen mode. Various effects can be achieved by selecting one among the hundreds of brushes available.

../../images/mypaint1.png

Result of 08-micro felt pen and glow pen by running the script twice

Next is another example with a pencil style chosen for the brush.

from os import system
from math import sin, cos, pi

x, y = 800, 640
xh, yh = x/2, y/2
a,b,d = 2,3,61
d = d*pi/180
n = 2
system('sleep 2; xdotool mousemove '+str(xh)+' '+str(yh))

for i in range(n*360+1):
    x,y = xh+yh*sin(a*i*d)*sin(b*i*d), yh+yh*cos(a*i*d)*sin(b*i*d)
    system('xdotool mousedown 1 mousemove '+str(x)+' '+str(y)+' mouseup 1')
    system('sleep 0.01')
../../images/mypaint2.png

Result of running the script with pencil

Interesting, yes?

Using integer relation algorithms to guess closed forms

In this post, we'll see about guessing closed forms of the answers obtained by numerical methods. In particular, we'll use the excellent math toolkit by David Bailey et. al. aimed at experimental mathematics -- arprec. Compile and run mathtool.

The following problems are taken from Brilliant

  1. \begin{equation*} \displaystyle \int_0^{\frac{\pi}{3}} x \left(\ln{\left(2 \sin{\frac{x}{2}}\right)}\right)^2 \, dx = \frac{c\, \pi^a}{b} \end{equation*}

    Find $a, b,$ and \(c\).

    Start mathtool, and enter the commands in sequence: (Only the relevent output is shown after command executions)

    integrate[x*log[2*sin[x/2]]^2,{x,0,pi/3}]
    -- snip --
    > 0.25554854129290762855238976168333131037737175253636607542005616591624
    epsilon=-50
    pslq[0.25554854129290762855238976168333131037737175253636607542005616591624, table[pi^i,{i,2,4}]]
    -- snip --
    > Relation:  0 =
    > +  6480.* pslq001
    > +     0.* pslq002
    > +     0.* pslq003
    > +   -17.* pslq004
    > Result[ 37] through Result[ 40] =
    >      6480.00000000000000000000000000000000000000000000000000000000000000000000
    >       0.00000000000000000000000000000000000000000000000000000000000000000000e0
    >       0.00000000000000000000000000000000000000000000000000000000000000000000e0
    >       -17.00000000000000000000000000000000000000000000000000000000000000000000
    

    So, the above output means, \(0= 6480\times 0.255548541292907628552389761683331310377371752536366075420056165916 - 17\times \pi^4\), and hence \(c=17, a=4, b=6480\)

    When doing such computations, it's good to have more digits when computing integral or sums, and reduce the epsilon value when using pslq, so that it checks for fewer decimal places when trying for an integer relation. Otherwise, it is likely to miss the relation when the numerical accuracy is kept high. digits=100 and epsilon=-50 worked well for me in most cases.

  2. \begin{equation*} \displaystyle \int_0^{2\log{\phi}} \log{\left(2\, \sinh{\frac{x}{2}}\right)} = -\frac{\pi^a}{b} \end{equation*}
    epsilon=-100
    integrate[log[2*(exp[x/2]-exp[-x/2])/2],{x,1e-100,2*log[(1+sqrt[5])/2]}]
    > -0.98696044010893586188344909998761511353136994072407906264133493762200
    epsilon=-50
    pslq[-0.98696044010893586188344909998761511353136994072407906264133493762200, table[pi^i,{i,1,4}]]
    > Relation:  0 =
    > +  10.* pslq001
    > +   0.* pslq002
    > +   1.* pslq003
    > +   0.* pslq004
    > +   0.* pslq005
    > Result[ 29] through Result[ 33] =
    >        10.00000000000000000000000000000000000000000000000000000000000000000000
    >       0.00000000000000000000000000000000000000000000000000000000000000000000e0
    >         1.00000000000000000000000000000000000000000000000000000000000000000000
    >       0.00000000000000000000000000000000000000000000000000000000000000000000e0
    >       0.00000000000000000000000000000000000000000000000000000000000000000000e0
    

    In this example, mathtool chokes when lower limit is 0 saying argument is too large, so keep it close to 0. Then using pslq, we see that a=2 and b=10.

  3. \begin{equation*} \displaystyle \int_{-\infty}^{\infty} \dfrac{\log{\left(1 + e^{2x}\right)}}{1 + e^{3\, x}} = \frac{a \pi^b}{c} \end{equation*}
    epsilon=-100
    Integrate[Log[1 + Exp[2*x]]/(1 + Exp[3* x]), {x, -Infinity, Infinity}]
    

    If we try to execute it directly, it complains "argument too large". So, we transform it by substituting \(e^x=y\)

    Integrate[Log[1 + y^2]/(1 + y^3)/y, {y, 0, Infinity}]
    > 0.59400396858408176872614992128884242944017635321356610251561824949472
    epsilon=-50
    pslq[0.59400396858408176872614992128884242944017635321356610251561824949472,table[pi^i,{i,1,5}]]
    > Relation:  0 =
    > +  216.* pslq001
    > +    0.* pslq002
    > +  -13.* pslq003
    > +    0.* pslq004
    > +    0.* pslq005
    > +    0.* pslq006
    > Result[  7] through Result[ 12] =
    >       216.00000000000000000000000000000000000000000000000000000000000000000000
    >       0.00000000000000000000000000000000000000000000000000000000000000000000e0
    >       -13.00000000000000000000000000000000000000000000000000000000000000000000
    >       0.00000000000000000000000000000000000000000000000000000000000000000000e0
    >       0.00000000000000000000000000000000000000000000000000000000000000000000e0
    >       0.00000000000000000000000000000000000000000000000000000000000000000000e0
    

    Hence, \(a=13, b=2, c=216\)

  4. \begin{equation*} \displaystyle \int_0^1 \log{x}\log{\left(1-x\right)} dx = \frac{a}{b}-\frac{\pi^c}{d} \end{equation*}
    epsilon=-100
    integrate[log[x]*log[1-x],{x,0,1}]
    > 0.35506593315177356352758483335397481078105009879320156226444177062999
    epsilon=-50
    pslq[0.35506593315177356352758483335397481078105009879320156226444177062999, 1,table[pi^i,{i,1,5}]]
    > Relation:  0 =
    > +  -6.* pslq001
    > +  12.* pslq002
    > +   0.* pslq003
    > +  -1.* pslq004
    > +   0.* pslq005
    > +   0.* pslq006
    > +   0.* pslq007
    > Result[ 27] through Result[ 33] =
    >        -6.00000000000000000000000000000000000000000000000000000000000000000000
    >        12.00000000000000000000000000000000000000000000000000000000000000000000
    >       0.00000000000000000000000000000000000000000000000000000000000000000000e0
    >        -1.00000000000000000000000000000000000000000000000000000000000000000000
    >       0.00000000000000000000000000000000000000000000000000000000000000000000e0
    >       0.00000000000000000000000000000000000000000000000000000000000000000000e0
    >       0.00000000000000000000000000000000000000000000000000000000000000000000e0
    

    Therefore, \(a=2, b=1, c=2, d=6\)

Compiling softwares that require later versions of GCC

Suppose we require to install the latest version of a software, but the repository doesn't have it, we usually either get the latest source code and compile, or download the compiled binary if available, and run it. But if we are running some old distro, latest binary refuse to run complaining that it requires GLIBC 2.16 to run etc. When the binary file refuses to run, we can then try to compile the source, which usually works fine. But sometimes it happens that the source requires a language standard, which is unsupported by the GCC version installed. In such cases, we can download the latest GCC, compile it, and then compile the required software using the latest GCC. We'll see an example to compile "Context Free" -- a program which generates art from a context free grammar, and requires C++11 standard to compile. The steps mentioned below were done on debian wheezy, whose software repository contains version 2 of cfdg whereas the latest version is 3.

In order to compile the latest version of contextfree in debian wheezy:

  • Download the latest GCC
  • Extract and configure with a prefix path, so that we can avoid installing it to a directory which requires root privilege
  • ./configure --prefix=$HOME/bin/custom_gcc
  • The compile and install to that path, the whole process takes much time anywhere between 10 mins to a couple of hours or more, depending on the speed of the machine and the number of cores used. To compile on a single core, use
    • make
    • make install

After GCC is installed, we need to indicate in the makefile of contextfree to use that version of GCC. So, add the following lines to the makefile, install libpng12-dev and compile.

1
2
3
4
CC = $(HOME)/bin/gcc_custom/bin/gcc
LD = $(HOME)/bin/gcc_custom/bin/gcc
CPP = $(HOME)/bin/gcc_custom/bin/g++
CXX = $(HOME)/bin/gcc_custom/bin/g++

The output cfdg can then be used as a standalone file. But we need to export some paths to run it, otherwise it'll complain about the older libraries. To get around that, we can create a small bash script to export the compiler and library paths and then run cfdg. E.g. create a script in $HOME/bin named cfdg with following contents

1
2
3
4
5
#!/bin/bash
export CC=$HOME/bin/gcc_custom/bin/gcc
export CXX=$HOME/bin/gcc_custom/bin/g++
export LD_LIBRARY_PATH=$HOME/bin/gcc_custom/lib64
$HOME/bin/context-free-3.0.9/cfdg "$@"

and chmod +x cfdg, and have fun with the software!

Installing and Running TensorFlow in Debian Wheezy

A couple of days ago google released what they term it as the second generation deep learning neural network software system, called TensorFlow. Google has been taking much interest in deep learning since two or three years (perhaps having surplus computation power?), and they are using it for all sorts of softwares they develop \(-\) maps, translation, spying on you for targeted ads etc. So, I thought of trying out their newly released tool.

First, I tried to install it using their "easy way" using virtualenv and pip. Getting into the virtual environment is easy, and pip install command also worked, but when importing tensorflow, it spit an ugly ImportError \(-\) /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.17' not found. Now, for the other option.

Next, I thought installing from sources would definitely go well. Downloaded all the source codes and dependencies required by the project, and bazel was one of them. Downloaded bazel as well, but when the installation script was run, that method also went kaput with some error complaining about the kernel version or something. Running from a virtual machine or installing some latest distro was my only option, I thought. But no! There's another method using docker image, which I overlooked even though that was mentioned at the top of the installation page.

Here are the steps:

  • Docker runs only on 64-bit OS with kernel version 3.10 or higher. So, the first step must be to install the latest kernel available from wheezy backports. Follow the backport instructions
  • Then reboot the machine selecting the latest kernel version
  • Follow the docker installation steps
  • Now, we are all set to install TensorFlow. Simply run
    • sudo docker run -it b.gcr.io/tensorflow/tensorflow
  • That will pull all the required dependencies and set the docker image (which was about 300MiB to download)
  • Wouldn't it be convenient if we could add some data persistance, to save data so that the host could use it? There's an option for that as well
    • sudo docker run -it -v /host/dir:/docker/dir b.gcr.io/tensorflow/tensorflow
  • Now the /host/dir is mounted to the /docker/dir when the image is run
  • And that's it, no need of a virtualbox, which wastes more time and space than to run a docker image
  • Check an example program from the tutorial, like plotting mandelbrot set