Monday, February 19, 2018

Python Code - Gauss's Circle Problem

This code uses the algorithm discussed here.

Iterative version of the code - Python

from math import sqrt, ceil, floor
from timeit import default_timer

start = default_timer()

def matmult (A, B):
    rows_A = len(A)
    cols_A = len(A[0])
    rows_B = len(B)
    cols_B = len(B[0])

    if cols_A != rows_B:
      print("Cannot multiply the two matrices. Incorrect dimensions.")
      return

    # Create the result matrix
    # Dimensions would be rows_A x cols_B
    C = [[0 for row in range(cols_B)] for col in range(rows_A)]

    for i in range(rows_A):
        for j in range(cols_B):
            for k in range(cols_A):
                C[i][j] += A[i][k] * B[k][j]
    return C

def gauss(n):
    sn = ceil(sqrt(n))
    res = 0
    stk = [([[1, 0, 0], [0, 1, 0], [0, 0, -n]], sn, sn)]
    while stk:
        m, w, h = stk.pop()
        if w <= 0 or h <= 0:
            continue
        a, b, c, d, e, f = m[0][0], 2 * m[0][1], m[1][1], 2 * m[0][2], 2 * m[1][2], m[2][2]
        if d * d - 4 * a * f < 0 or e * e - 4 * c * f < 0:
            res += w * h
            continue
        x0, y0 = (- d + sqrt(d * d - 4 * a * f)) / 2 / a, (- e + sqrt(e * e - 4 * c * f)) / 2 / c
        xint, yint, uint, vint, flag = 0, 0, 0, 0, 0
        if floor(x0) == ceil(x0):
            xint = 1
        if floor(y0) == ceil(y0):
            yint = 1
        if w <= 1:
            res += (h - ceil(y0)) * w - yint
            continue
        if h <= 1:
            res += (w - ceil(x0)) * h - xint
            continue
        if w - x0 > 1:
            res += (w - ceil(x0)) * h - xint
            stk.append((m, ceil(x0), h))
            continue
        if h - y0 > 1:
            res += (h - ceil(y0)) * w - yint
            stk.append((m, w, ceil(y0)))
            continue
        temp = (a - b + c) * (c * d * d - b * d * e + a * e * e + b * b * f - 4 * a * c * f)
        if temp < 0:
            continue
        u = ((a - b + c) * (b * e - 2 * c * d) - (b - 2 * c) * sqrt(temp)) / (a - b + c) / (4 * a * c - b * b)
        if floor(u) == ceil(u):
            uint = 1
        if u > w:
            u, flag = w, 1
        if u < 0:
            u, flag = 0, 1
        temp = (e  + b * u) * (e + b * u) - 4 * c * (f + u * (d + a * u))
        if temp < 0:
            continue
        v = (- e - b * u + sqrt(temp)) / 2 / c
        if floor(v) == ceil(v):
            vint = 1
        if v < 0:
            v = 0
        u, v = ceil(u), ceil(v)
        if u == w and v == h:
            continue
        if uint == 1 and vint == 1 and flag == 0:
            res -= 1
        res += (w - u + h - 1 - v) * (w - u + h - v) // 2
        stk.append((matmult(matmult([[1, 0, 0], [-1, 1, 0], [h - v, v, 1]], m), [[1, -1, h - v], [0, 1, v], [0, 0, 1]]), u - (h - v), h - v))
        stk.append((matmult(matmult([[1, -1, 0], [0, 1, 0], [u, w - u, 1]], m), [[1, 0, u], [-1, 1, w - u], [0, 0, 1]]), w - u, v - (w - u)))
    res = (sn - 1) * (sn - 1) - res
    res += sn - 1
    res *= 4
    res += 1
    if sn * sn == n:
        res += 4
    return res

print(gauss(10 ** 20))
print(default_timer() - start)


Recursive version of the code - Python

from math import sqrt, ceil, floor
from timeit import default_timer

start = default_timer()

def matmult (A, B):
    rows_A = len(A)
    cols_A = len(A[0])
    rows_B = len(B)
    cols_B = len(B[0])

    if cols_A != rows_B:
      print("Cannot multiply the two matrices. Incorrect dimensions.")
      return

    # Create the result matrix
    # Dimensions would be rows_A x cols_B
    C = [[0 for row in range(cols_B)] for col in range(rows_A)]

    for i in range(rows_A):
        for j in range(cols_B):
            for k in range(cols_A):
                C[i][j] += A[i][k] * B[k][j]
    return C

def poins(m, w, h):
    res = 0
    if w <= 0 or h <= 0:
        return 0
    a, b, c, d, e, f = m[0][0], 2 * m[0][1], m[1][1], 2 * m[0][2], 2 * m[1][2], m[2][2]
    if d * d - 4 * a * f < 0 or e * e - 4 * c * f < 0:
        return w * h
    x0, y0 = (- d + sqrt(d * d - 4 * a * f)) / 2 / a, (- e + sqrt(e * e - 4 * c * f)) / 2 / c
    xint, yint, uint, vint, flag = 0, 0, 0, 0, 0
    if floor(x0) == ceil(x0):
        xint = 1
    if floor(y0) == ceil(y0):
        yint = 1
    if w <= 1:
        return (h - ceil(y0)) * w - yint
    if h <= 1:
        return (w - ceil(x0)) * h - xint
    if w - x0 > 1:
        return (w - ceil(x0)) * h - xint + poins(m, ceil(x0), h)
    if h - y0 > 1:
        return (h - ceil(y0)) * w - yint + poins(m, w, ceil(y0))
    temp = (a - b + c) * (c * d * d - b * d * e + a * e * e + b * b * f - 4 * a * c * f)
    if temp < 0:
        return 0
    u = ((a - b + c) * (b * e - 2 * c * d) - (b - 2 * c) * sqrt(temp)) / (a - b + c) / (4 * a * c - b * b)
    if floor(u) == ceil(u):
        uint = 1
    if u > w:
        u, flag = w, 1
    if u < 0:
        u, flag = 0, 1
    temp = (e  + b * u) * (e + b * u) - 4 * c * (f + u * (d + a * u))
    if temp < 0:
        return 0
    v = (- e - b * u + sqrt(temp)) / 2 / c
    if floor(v) == ceil(v):
        vint = 1
    if v < 0:
        v = 0
    if uint == 1 and vint == 1 and flag == 0:
        res -= 1
    u, v = ceil(u), ceil(v)
    if u == w and v == h:
        return 0
    res += (w - u + h - 1 - v) * (w - u + h - v) // 2
    res += poins(matmult(matmult([[1, 0, 0], [-1, 1, 0], [h - v, v, 1]], m), [[1, -1, h - v], [0, 1, v], [0, 0, 1]]), u - (h - v), h - v)
    res += poins(matmult(matmult([[1, -1, 0], [0, 1, 0], [u, w - u, 1]], m), [[1, 0, u], [-1, 1, w - u], [0, 0, 1]]), w - u, v - (w - u))
    #print(m, w, h, u, v, res)
    return res

def gauss(n):
    m = ceil(sqrt(n))
    res = poins([[1, 0, 0], [0, 1, 0], [0, 0, -n]], m, m)
    res = (m - 1) * (m - 1) - res
    res += m - 1
    res *= 4
    res += 1
    if m * m == n:
        res += 4
    return res

print(gauss(10 ** 14))

print(default_timer() - start)


Recursive version of the code


Clear["Global`*"];
Poins[m0_, w0_, h0_] :=
  Poins[m0, w0, h0] =
   Block[{$RecursionLimit = Infinity, m = m0, w = w0, h = h0, a, b, c,
      d, e, f, temp, u, v, res = 0, trans, x0, y0, Flag = 0},
    If[Or[w <= 0, h <= 0], Return[0];];
    If[w < h,
     temp = {{0, 1, 0}, {1, 0, 0}, {0, 0, 1}};
     m = Transpose[temp].m.temp;
     temp = w; w = h; h = temp;
     ];
    a = m[[1, 1]]; b = 2 m[[1, 2]]; c = m[[2, 2]]; d = 2 m[[1, 3]];
    e = 2 m[[2, 3]]; f = m[[3, 3]];
    If[Or[d*d - 4*a*f < 0, e*e - 4*c*f < 0], Return[w h];];
    x0 = (-d + Sqrt[d*d - 4*a*f])/2/a;
    y0 = (-e + Sqrt[e*e - 4*c*f])/2/c;
    If[w <= 1, Return[(h - Ceiling[y0]) w - Boole[IntegerQ[y0]]];];
    If[h <= 1, Return[(w - Ceiling[x0]) h - Boole[IntegerQ[x0]]];];
    If[w - x0 > 1,
     Return[(w - Ceiling[x0]) h - Boole[IntegerQ[x0]] +
        Poins[m, Ceiling[x0], h]];
     ];
    If[h - y0 > 1,
     Return[(h - Ceiling[y0]) w - Boole[IntegerQ[y0]] +
        Poins[m, w, Ceiling[y0]]];
     ];
    temp = (a - b + c)*(c*d*d - b*d*e + a*e*e + b*b*f - 4*a*c*f);
    If[temp < 0, Return[0];];
    u = ((a - b + c)*(b*e - 2*c*d) - (b - 2*c)*Sqrt[temp])/(a - b +
         c)/(4*a*c - b*b);
    If[u > w, u = w; Flag = 1;];
    If[u < 0, u = 0; Flag = 1;];
    temp = (e + b*u)*(e + b*u) - 4*c*(f + u*(d + a*u));
    If[temp < 0, Return[0];];
    v = (-e - b*u + Sqrt[temp])/2/c;
    If[v < 0, v = 0;, v = Ceiling[v];];
    If[And[IntegerQ[u], IntegerQ[v], Flag == 0], res -= 1;];
    u = Ceiling[u]; v = Ceiling[v];
    If[And[u == w, v == h], Return[0];];
    res += (w - u + h - 1 - v)*(w - u + h - v)/2;
    trans = {{1, -1, h - v}, {0, 1, v}, {0, 0, 1}};
    res += Poins[Transpose[trans].m.trans, u - (h - v), h - v];
    trans = {{1, 0, u}, {-1, 1, w - u}, {0, 0, 1}};
    res += Poins[Transpose[trans].m.trans, w - u, v - (w - u)];
    res
    ];
GaussCnt[n0_] := Block[{n = n0, m, res},
   m = Ceiling[Sqrt[n]];
   res = Poins[{{1, 0, 0}, {0, 1, 0}, {0, 0, -n}}, m, m];
   res = (m - 1)*(m - 1) - res;
   res += m - 1; res *= 4; res += 1;
   If[m m == n, res += 4;];
   res
   ];
Rad = Power[10, 6];
GaussCnt[Rad*Rad] // AbsoluteTiming



Note that in all the codes, the core function takes as input the square of the radius of the circle under consideration.



Until then
Yours Aye
Me

A Sub-linear algorithm for Gauss's Circle problem


I was proud of my previous two posts, I thought I would not have anything that I can share for a while. But I'm glad I found something very interesting.

I found this PDF titled A Successive approximation Algorithm for Computing the Divisor Summatory function a long time back (in OEIS I think). It has an $O(n^{1/3})$ for calculating the divisor summatory function. I have read this many times both because I find it interesting and I could not fully understand the tiny details though I got the crux of what the algo is trying to do.

I was reading it again some time last week and was on page 6. The PDF uses the properties of a Hyperbola to do the summation and the author quotes "... the hyperbolic segment has the same basic shape as the full hyperbola" and then suddenly it hit me. After all, the Hyperbola is a conic section and if it holds for a hyperbola, why not a different conic? And if that conic is an Ellipse (of which Circle is a special case), then pretty much the same algo should solve Gauss's Circle problem. Indeed it did.

As I said earlier, I could not get all the details of the original algo and I proceeded in a more natural way. In essence, let

$C(x,y)=Ax^2+Bxy+Cy^2+Dx+Ey+F=0$ be a conic section with an increasing slope in the first quadrant bounded by the lines $x=w$ and $y=h$.

Then we will the counting the lattice points such that,

$0 \leq x < w$, $0 \leq y < h$ and $C(x,y) > 0$

Consider the first quadrant of the circle as shown in the left figure below. Now we can draw an 'almost' tangent with a slope of $-1$ as shown in the right figure below. Let $(u,v)$ be the almost tangent point (shown as a black dot).

 

Now it's we can simply count the number of lying inside the triangle that don't violate our conditions in $O(1)$ time. We can then make two parallelograms such that they cover our region of interest. Something like in the figure below.


Now comes the beautiful part. Let's concentrate on the parallelogram above. The reasoning will be almost similar to the other parallelogram except for a tiny detail.

We can transform the co-ordinate system now such that the lower left corner of the upper parallelogram becomes the origin. In addition to this, the parallelogram can be sheared horizontally such that the parallelogram becomes a rectangle. Simply put, we are trying to do the following:





Here the first figure, which is the upper parallelogram, after shifting the origin and shearing becomes the second figure. Note that the number of lattice points inside both the figures remain the same after this operation. This fact can be understood by a bit of linear algebra but let's not get into the details.

Now we are in the same situation as before. We have a conic, a bounding rectangle and we have to count the points inside the rectangle and outside the conic. This essentially forms the crux of the recursion.

The almost tangent point can be found as the point of intersection of the conic and the tangent (with a slope of $-1$) equation of the same conic. Mathematica solves the symbolic equation in the blink of an eye.

The 'exact' point of intersection $(u, v)$ is found to be,

$u_e=\displaystyle\frac{(A-B+C)(BE-2CD)-(B-2C)\sqrt{\Delta_u}}{(A-B+C)(4AC-B^2)}$ and $v_e=\displaystyle\frac{-C-Bu+\sqrt\Delta_v}{2C}$

where $\Delta_u=(A - B + C) (CD^2 - BDE + AE^2 + B^2F - 4ACF)$ and $\Delta_v=(E+Bu)^2 - 4C(F + u (D + Au))$

The almost tangent point can be found by setting $u=\lceil u_e \rceil$ and $v=\lceil v_e \rceil$.

Now the transformation. These can be attained beautifully with matrices. A Conic can be represented as a matrix in the following way.

$C=\mathbf{x}^T A_Q\mathbf{x}$

where the matrix $A_Q$ is given in Matrix representation of Conic Sections. Now the 'shifting and shearing' operations can be done using the following two matrices.

$X=\begin{pmatrix}1 & -1 & h-v\\0 & 1 & v \\0&0&1\end{pmatrix}$ and $Y=\begin{pmatrix}1 & 0 & u\\-1 & 1 & w-u \\0&0&1\end{pmatrix}$

Now the matrix $X^TA_QX$ gives the conic after we have translated the origin to $(u, v)$ and sheared it horizontally and vice versa for the vertical shearing using matrix $Y$.

Finally, though we start with a simple conic, the conics that subsequently results in further recursion are a little tricky and there are a number of cases that have to dealt with carefully. A better programmer could've done it in a day or two, but it took me almost ten days to finally complete the code. You can find the recursive and the iterative version of the Python code in this post.

Assuming no precision issues, the iterative version of the code finds $N(10^{9})=3141592653590319313$ in about 5 mins and $N(10^{10})=314159265359046103545$ in about 20 mins. The timing could be halved by taking the eight-fold symmetry of a circle but I didn't do it yet.

Hope you enjoyed it. See ya in the next post.


Until then
Yours Aye
Me

Sunday, January 21, 2018

Complicating a simple Probability Problem II


Hi all, we complicated a simple problem in Probability in the previous post. Here again, we do the same thing.

The setup is this. Consider the unit interval $(0, 1)$. We start at the origin and choose $n$ random points in the interval that lies to the right. We now choose the $k$th point nearest to the origin and move there. We again choose $n$ points in the interval that lies to the right and keep moving to the right until we get inside an interval $[0, x)$ for a given $x$.

Let $\mathbb{E}_{n,k}(x)$ be the expected number of times we have to generate the numbers (or in other words, the moves we have to make). So as you may have guessed, this post about finding this number.

Okay, the procedure pretty much follows what we saw the previous time. It gets all messy and I'm not even sure how to present it. So I'm directly giving the result.

Let $P_{n,k}(z)$ denote the characteristic equation. We have,

$P_{n,k}(z)=\displaystyle\frac{z^\underline{n}}{n!}-(-1)^{n-k}\sum_{j=0}^{n-k}(-1)^j\binom{n-1-j}{k-1}\frac{z^\underline{j}}{j!}$

where $z^\underline{n}$ is the falling factorial.

Let $\eta_1,\eta_2,\cdots,\eta_n$ be the $n$ roots of the equation $P_{n,k}(z)=0$. Then we have,

$\begin{align}
\mathbb{E}_{n,k}(x)=\displaystyle\frac{H_n-\log{x}}{H_n-H_{n-k}}&+\frac{x^n}{n!}\sum_{r=1}^n\frac{x^{-\eta_r}\eta_r^\underline{n}}{\eta_rP'_{n,k}(z)}\\
&-\displaystyle\frac{x^nn^{n-1}}{n!(H_n-H_{n-k})}\sum_{r=1}^n\sum_{i=0}^{n-1}\sum_{j=0}^i\frac{(n-i)x^{-\eta_r}\eta_r^\underline{n}\eta_r^{j-1}a_{i-j}}{n^{i}P'_{n,k}(\eta_r)}
\end{align}$

where $a_m=[z^{n-m}]P_{n,k}(z)$ and $H_n$ is the $n$th Harmonic number.

Using this, we can see that

$\mathbb{E}_{n,1}(x)=1-n\log{x}$

$\mathbb{E}_{n,2}(x)=1+\displaystyle\frac{n(n-1)}{(2n-1)^2}(x^{2n-1}-1)-\frac{n(n-1)\log{x}}{2n-1}$

Considering the number of identities involving the falling factorials, there seems to enough room for simplifying the above formula but am not able to see things clearly. I think adding an animation would make it more easy to see what the 'procedure' means and am on it. I'll update it as soon as possible.


Until then
Yours Aye
Me

Friday, January 12, 2018

Complicating a simple Probability problem


This problem is all about taking a simple problem in probability and complicating it.

Consider the problem of finding the expected number of uniform variables between $0$ and $1$ needed to get a sum greater than $1$. This problem is well studied and surprisingly the answer turns out to be $e$, Euler's number.

The derivation goes something like this. Starting with $0$, we keep generating Uniform random variable $X \sim U(0,1)$ and adding them until we exceed $1$. Let $\mathbb{E}(x)$ be the expected number of random variables needed when we start from $x$.

It's easy to that $\mathbb{E}(x)=0$ for $x>1$ and $E(1)=1$, both by problem definition.

Now it's easy to write the following equation.

$\mathbb{E}(x)=1+\displaystyle\int\limits_0^1\mathbb{E}(x+t)\,dt$

Now let $y=x+t$. The only thing to take care is when $t=1$, $y=1+x$. But we already know that expected value is $0$ for a value exceeding $1$. Hence, we can only consider the integral with $1$ as the upper limit.

$\mathbb{E}(x)=1+\displaystyle\int\limits_x^1\mathbb{E}(y)\,dy$

For reasons that'll be apparent later in this post, let's define a family of functions $f_k(z)$ such that $f_k^{(k)}(z)=D^k f_k(z)=\mathbb{E}(z)$ and $f_k(1)=0$, $k > 0$. Here the bracketed exponents denotes differentiation and $D$ denotes the differentiation operator.

Using this definition, the equation above becomes,

$\begin{align}
f_1'(x)&=1+\displaystyle\int\limits_x^1\,df_1\\
&=1+f_1(1)-f_1(x)\\
&=1-f_1(x)
\end{align}$

Therefore, we end up with the differential equation $f'_1(x)+f_1(x)=1$.

Solving this with Wolfram alpha, we get $f_1(x)=1+c_1e^{-x}$.

But $\mathbb{E}(x)=f_1'(x)=-c_1 e^{-x}$. Using the boundary condition, $\mathbb{E}(1)=1$, we get $\mathbb{E}(x)=e^{1-x}$ and hence $\mathbb{E}(0)=e$.             $\blacksquare$

Now we make a slight modification. Instead of just generating one random number each time, what if we generate a bunch of $n$ uniform random numbers and choose the minimum of those to be the addend. Now we seek the expected number of random numbers added. We know that the pdf of the minimum of $n$ numbers is,

$pdf(z)=n(1-z)^{n-1}$, $0 \leq z \leq 1$

Therefore the integral equation we start with becomes,

$\mathbb{E}_{n,1}(x)=1+\displaystyle\int\limits_0^1\mathbb{E}_{n,1}(x+t)n(1-t)^{n-1}\,dt$

Note that $\mathbb{E}_{n,1}(1)=1$. Using $y=x+t$,

$\displaystyle\mathbb{E}_{n,1}(x)=1+n\int\limits_x^1\mathbb{E}_{n,1}(y)(1+x-y)^{n-1}\,dy$

Using the $f$ functions, we can transform the equation to,

$f_1'(x)=1-n f_1(x)+n(n-1)\int\limits_x^1f_1(y)(1+x-y)^{n-2}\,dy$

Now this can be repeatedly applied until the exponents inside the integral becomes $0$. We'll finally end-up with,

$\displaystyle \frac{f_n^{(n)}(x)}{n!}+\frac{f_n^{(n-1)}(x)}{(n-1)!}+\frac{f_n^{(n-2)}(x)}{(n-2)!}+\cdots+f_n(x)=\frac{1}{n!}$

Or using the differential operator,

$\displaystyle \left(\frac{D^n}{n!}+\frac{D^{n-1}}{(n-1)!}+\frac{D^{n-2}}{(n-2)!}+\cdots+1\right)f_n(x)=\frac{1}{n!}$

The characteristic equation of the differential equation is the partial exponential sum function. Let $P_{n,1}(m)$ denote this characteristic of equation and let $\eta_1,\eta_2,\cdots,\eta_n$ be the roots. That is,

$P_{n,1}(z)=\displaystyle 1+z+\frac{z^2}{2!}+\frac{z^3}{3!}+\cdots+\frac{z^n}{n!}$

Note that $P'_{n,1}(z)=P_{n-1,1}(z)$. Also, as

$P_{n,1}(z)=(z-\eta_1)(z-\eta_2)(z-\eta_3)\cdots(z-\eta_n)$

we have, $P'_{n,1}(\eta_i)=\displaystyle\prod_{i \ne j,1 \leq j \leq n}(\eta_i-\eta_j)=P_{n-1,1}(\eta_i)$

Back to the differential equation, $f_n(x)=\frac{1}{n!} + c_1 e^{\eta_1x}+ c_2 e^{\eta_2x}+ c_3 e^{\eta_3x}+\cdots+ c_n e^{\eta_nx}$

$f_n^{(k)}(x)=c_1 \eta_1^ke^{\eta_1x}+ c_2 \eta_2^ke^{\eta_2x}+ c_3\eta_3^k e^{\eta_3x}+\cdots+ c_n \eta_n^ke^{\eta_nx}$, $0\leq k\leq n$

Before solving for the constants, by this time we should realize that the constant in the RHS of the starting integral equation doesn't matter as it'll be taken care by the boundary conditions. The other constants can be solved by the conditions we enforced on the $f$ functions.

$f_n^{(k)}(1) = 0$ for $k<n$ and $f_n^{(n)}(1)=\mathbb{E}(1)=1$.

The post is getting unusually long. So I'll cut short the details. Solving for the constants using determinants, we'll have,

$\mathbb{E}_{n,1}(x)=\displaystyle\frac{1}{n!}\sum_{i=1}^n \frac{e^{-\eta_i(1-x)}\eta_i^{n-1}}{P_{n-1,1}(\eta_i)}$ and hence $\mathbb{E}_{n,1}(0)=\displaystyle\frac{1}{n!}\sum_{i=1}^n \frac{e^{-\eta_i}\eta_i^{n-1}}{P_{n-1,1}(\eta_i)}$       $\blacksquare$

Now for the final complication, what if we generate a bunch of $n$ random uniform numbers, sort them and choose the $k$th smallest number as the addend? Let $\mathbb{E}_{n,k}(x)$ be the expected value. The only thing of importance is the characteristic equation denoted as $P_{n,k}(z)$.

$P_{n,k}(z)=\displaystyle \frac{z^n}{n!}-(-1)^k \sum_{j=0}^{n-k}\binom{n-1-j}{k-1}\frac{z^j}{j!}$

That is, $P_{n,k}(D)f_n(x)=\frac{1}{n!}$

Note that still,  $P'_{n,k}(z)=P_{n-1,k}(z)$ and $P'_{n,k}(\eta_i)=\displaystyle\prod_{i \ne j,1 \leq j \leq n}(\eta_i-\eta_j)=P_{n-1,k}(\eta_i)$

And the same analysis shows,

$\mathbb{E}_{n,k}(x)=\displaystyle\frac{1}{n!}\sum_{i=1}^n \frac{e^{-\eta_i(1-x)}\eta_i^{n-1}}{P_{n-1,k}(\eta_i)}$ and hence $\mathbb{E}_{n,k}(0)=\displaystyle\frac{1}{n!}\sum_{i=1}^n \frac{e^{-\eta_i}\eta_i^{n-1}}{P_{n-1,k}(\eta_i)}$

One of the beautiful things to note here is that the nature of the final formula gives a interpretation via the contour integral. That is,

$\mathbb{E}_{n,k}(x)=\displaystyle\frac{1}{n!}\sum_{i=1}^n \frac{e^{-\eta_i(1-x)}\eta_i^{n-1}}{P_{n-1,k}(\eta_i)}=\frac{1}{2\pi i n!}\oint_{\Gamma}\frac{e^{-z(1-x)}z^{n-1}}{P_{n,k}(z)}\,dz$

where the contour $\Gamma$ is large enough to encompass all the zeroes of $P_{n,k}(z)$.

Using these I was able to find,

$\mathbb{E}_{1,1}(0)=e$, $\mathbb{E}_{2,1}(0)=e(\cos 1 + \sin 1)$ and $\mathbb{E}_{2,2}(0)=\cosh \sqrt 2$,

The other characteristic equations does not appear to have closed form solutions. But the next simpler things are $\mathbb{E}_{n,n}(0)$.

$\mathbb{E}_{n,n}(0)={}_0F_{n-1}(;1/n,2/n,\cdots,(n-1)/n;n^n/n!)$

where ${}_pF_q(z)$ is the generalized hyper-geometric function.

Solving the characteristic equations is the real trouble and I tried to find some simpler ways to do that without success. However I was able to establish,

$\mathbb{E}_{n,k}(0)\approx \displaystyle \frac{n+1}{k}\left(1+\frac{1}{2}\frac{k+1}{n+2}\right)$

This approximation is very good even when $n$ and $k$ are far apart.

I tried to cover the derivations too but the post is getting longer. Maybe I'll post them separately and break this into shorter ones.


Until then,
Yours Aye
Me

Sunday, January 7, 2018

A Note on Conditional Expectations


This post is about a very small problem on conditional expectations but which got me thinking for a couple of days. Eventually I realized how I never really fully understood them.

The problems is this: Let $X, Y$ be two random variables uniformly distributed between $0$ and $1$. Find $\mathbb{E}(X\vert X+Y \leq 1)$.

I was discussing with a friend and he even tried to write the Bayes formula for exceptions. Only when I started thinking about this I realized, how may people, including me, don't see the absurdity of trying to find Expectation of events and Probability of variables.

For example, $\mathbb{E}(X+Y \leq 1)$ doesn't make any sense at all. Neither does $\mathbb{P}(X)$. Both of them completely nonsensical. For the first one to make sense, it would be more appropriate to talk about $\mathbb{E}(I_{X+Y \leq 1})$ where $I$ is an indicator random variable. Similarly, $\mathbb{P}(0.25\leq X \leq 0.5)$ is valid expression.

Let $X$ be a variable and $Z$ be an event, something like $X+Y\leq1$ or $X \geq Y$. Let $I_Z$ be the indicator random variable of the event $Z$. Now, conditioning on $Z$,

$\begin{align}\mathbb{E}(X\cdot I_z)&=\mathbb{P}(Z)\mathbb{E}(X\cdot I_z\vert Z)+\mathbb{P}(Z^c)\mathbb{E}(X\cdot I_z \vert Z^c)\\
&=\mathbb{P}(Z)\mathbb{E}(X\cdot 1\vert Z)+\mathbb{P}(Z^c)\mathbb{E}(X\cdot 0\vert Z^c)\\
&=\mathbb{P}(Z)\mathbb{E}(X\vert Z)\\
\end{align}$

On the other hand, conditioning on $X$,

$\begin{align}\mathbb{E}(X\cdot I_z)&=\mathbb{E}(\mathbb{E}(X\cdot I_z \vert X))\\
&=\mathbb{E}(X\cdot \mathbb{E}(I_z\vert X))\\
&=\mathbb{E}(X\cdot \mathbb{P}(Z\vert X))
\end{align}$

Equating the two, we finally get,

$\mathbb{E}(X\vert Z)=\displaystyle\frac{\mathbb{E}(X\cdot \mathbb{P}(Z\vert X))}{\mathbb{P}(Z)}$

Now this makes the problem tractable, as all the terms makes perfect sense provided we understand that $X$ is a variable and $Z$ is an event (which could even be something like $X=3$ in the discrete case).

An alternate way of deriving the same result will be like the following. Assume $X$ is a continuous random variable. The reasoning will be very similar if $X$ is discrete.

$\begin{align}
\mathbb{E}(X\vert Z)&=\int x f_{X\vert Z}(x)\,dx\\
&=\int x \text{ }\frac{\mathbb{P}(Z\vert X)f_{X}(x)}{\mathbb{P}(Z)}\,dx=\displaystyle\frac{1}{\mathbb{P}(Z)}\int x\text{ } \mathbb{P}(Z\vert X)f_{X}(x)\,dx\\
&=\displaystyle\frac{\mathbb{E}(X\cdot \mathbb{P}(Z\vert X))}{\mathbb{P}(Z)}
\end{align}$

However, the first way includes a lot of tiny beautiful details like the conditioning on a random variable, law of total expectation, and most importantly it gives a chance to understand that,

$\mathbb{E}(X\cdot I_z\vert I_z=1)\ne\mathbb{E}(X)$ in general. Rather when the dependence between $X$ and $Z$ is not clear or not given, it is always better to state the relation as,

$\mathbb{E}(X\cdot I_z\vert I_z=1)=\mathbb{E}(X\vert Z)$

That's what I wanted to convey in this post because I had a very difficult time on how to solve that conditional expectation. Hope you enjoyed this.


Until then
Yours Aye,
Me

Thursday, January 4, 2018

Visualizing Conformal Mapping with Mathematica


Hi everyone, My first post in 2018..

Well, this post does not have any mathematics. Rather, this post is about, as the title says, visualizing conformal mapping. I recently came across an amazing Youtube Channel, 3Blue1Brown. If you haven't seen it, you should definitely check it out.

Most of the videos are pretty amazing. If you think Mathematics is beautiful with just equations, then visualizing Math is possibly the only thing better than Math itself (in my humble opinion).

Especially the video Visualizing the Riemann Zeta function is outstanding, simply the best video I've seen on Youtube, I think. Ever since I saw that, I wanted to create those animations. A simple Google search led me the fact that Grant Sanderson, creator of the Channel, uses his own Python module manim to create these animations.

I'm just a beginner in Python and using a specialized module is far from my relationship with Python. So I turned to the next best thing at my disposal, Mathematica. It took me about four evenings to get everything right to get an Animation and save it as GIF using Mathematica. But now after seeing those animations, I feel like it's really worth it.

So here's one of my first animations. The Inverse of a complex number.



Pretty neat, don't you think?

Now for the Zeta function itself. Mathematica takes about 5 mins to create the following animation.



Look at that.. So beautiful...

Moreover, looking at the two mappings we can get to see how the Zeta function has a simple pole at 1. Both graphs look almost the same at the final stage except that the Zeta function is translated by a unit distance along the real axis.

I also created one with a darker background but it doesn't look all that nice. The different colors are not by choice. In fact I'm not sure how to make all the curves along the real axis look the same color. Hope you would let me know in case you are aware of that.

Now for the code.

Clear["Global`*"];
f[z_] := Zeta[z];
Lim = 5;
DiscreteXValues =
 Join[Range[-Lim, -2], Table[j/10, {j, -15, 15}],
  Range[2, Lim]]; ContinuousYValues = {-Lim, Lim};
DiscreteYValues =
 Join[Range[-Lim, -2], Table[j/10, {j, -15, 15}],
  Range[2, Lim]]; ContinuousXValues = {-Lim, Lim};
RangeofthePlot = {{-Lim, Lim}, {-Lim, Lim}};
slides = Table[
    Show[ParametricPlot[
      Evaluate[
       Table[{XVaries (1 - t) + t Re[f[XVaries + I k]],
         k (1 - t) + t Im[f[XVaries + I k]]}, {k,
         DiscreteYValues}]], {XVaries, First[ContinuousXValues],
       Last[ContinuousXValues]}],
     ParametricPlot[
      Evaluate[
       Table[{k (1 - t) + t Re[f[k + I YVaries]],
         YVaries (1 - t) + t Im[f[k + I YVaries]]}, {k,
         DiscreteXValues}]], {YVaries, First[ContinuousYValues],
       Last[ContinuousYValues]}], PlotRange -> RangeofthePlot,
     AxesOrigin -> {0, 0}, GridLines -> Automatic], {t, 0, 1,
     1/40}]; // AbsoluteTiming
ListAnimate[slides, AnimationDirection -> ForwardBackward,
 AnimationRunning -> True, AnimationRate -> 8]
(*Export["ZetaFunction.gif",slides,ConversionRules\[Rule]{\
"ControlAppearance"\[Rule]None,"DisplayDurations"\[Rule]1/5}]*)
Export["ZetaFunction.gif",
 Flatten[{slides,
   Table[slides[[i]], {i, Length[slides] - 1, 2, -1}]}],
 "ControlAppearance" -> None, "DisplayDurations" -> 1/8]

After several iterations, I ended up with the above. It has options to control how many grid lines you want in each direction, and for each of them how long you wanna plot in the perpendicular direction. Play with DiscreteXValues, DiscreteYValues, ContinuousXValues and ContinuousYValues.

And before I finish, while we are on the 3Blue1Brown, his video on Pi hiding in prime irregularities, inspired me to find the following two 'non-obvious' results.

$\displaystyle \frac{\sqrt{2}\pi}{5}=\left\vert \frac{1}{1} + \frac{i}{2}- \frac{i}{3} - \frac{1}{4} + \frac{1}{5} + \frac{i}{6} - \frac{i}{7} - \frac{1}{8} + \cdots\right\vert$

$\displaystyle \frac{\pi}{\sqrt{10}}=\left\vert \frac{1}{1} + \frac{i}{3}- \frac{i}{7} - \frac{1}{9} + \frac{1}{11} + \frac{i}{13} - \frac{i}{17} - \frac{1}{19} + \cdots\right\vert$

Hope you enjoyed them.



Until then,
Yours Aye
Me.

Saturday, December 30, 2017

A little math on Badminton


If you had read my first few posts, you would've known that am an amateur Badminton player. Now I don't find either the time or the energy to play the game, but it's a game that I've always enjoyed playing. This post is about combining my interest on Badminton and my passion for math.

Most of the important details of the post are borrowed from Score probabilities for serve and rally competitions. The paper was too good in analyzing a given serve-rally competition, be it tennis or Badminton or the likes, the paper did not stick to any one particular game and finish it off in style which is exactly what we plan to do here for Badminton.

Let's just list the rules to make sure we are all on the same page.

  • A rally cannot end in a draw
  • The winner of the current rally wins a point and serves next irrespective of who served the current rally
  • The first player to reach 21 points wins the game unless the score was ever tied at 20 apiece
  • If the score ever reached 20-20, then the first player to lead by two point or the reach 30 points wins the game

Let me stick to the notations used in the paper quoted above and call the two players $A$ and $B$. WLOG, we always consider $A$ to serve first. The game will be analyzed from $A$'s perspective and hence let $p_a$ denote the probability that $A$ wins the rally when $A$ serves and $p_b$ denote the probability that $A$ wins the rally when $B$ serves.

Then $q_x=1-p_x,\text{ }x=a,b$ be the corresponding winning probabilities for $B$.

Given these probabilities, we intend to find the probability of $A$ winning the game. But before we begin, assuming both the players are equally skilled, do you think that $A$ has an advantage because he is serving first?

Let $\mathbb{P}(X),\text{ } X=A,B$ denote the probability that $X$ wins the game and $\mathbb{P}(X_{i,j}),\text{ } X=A,B$ denote the probability that game is at a stage where $A$ has $i$ points, $B$ has $j$ points and $X$ has won the last point.

The paper doesn't go on to complete by taking into account the end conditions of the game. To do that, we extend it to cover the end cases as well.

$\mathbb{P}(A_{i,j})=
\begin{cases}
0,& i \leq 0\\
p_a^i, &i\leq21,j=0\\
\displaystyle p_a^iq_b^j\sum_{r=1}^i\binom{i}{r}\binom{j-1}{r-1}\left(\frac{q_a p_b}{p_a q_b}\right)^r,&i < 21, j<21\text{ (or) }i=21,j<20\\
p_a\text{ }\mathbb{P}(A_{i-1,j})+p_b\text{ }\mathbb{P}(B_{i-1,j}),&0\leq i - j \leq 2, \text{ }i\leq30,j<30
\end{cases}$

$\mathbb{P}(B_{i,j})=
\begin{cases}
0,& j \leq 0\\
q_a q_b^{j-1}, &j\leq21,i=0\\
q_a q_b^{j-1}p_a^i\left[1+\displaystyle\sum_{s=1}^{j-1}\sum_{r=1}^i\binom{i}{r}\binom{s-1}{r-1}\left(\frac{q_a p_b}{p_a q_b}\right)^r\right],&j < 21, i<21\text{ (or) }j=21,i<20\\
q_a\text{ }\mathbb{P}(A_{i,j-1})+q_b\text{ }\mathbb{P}(B_{i,j-1}),&0\leq j-i \leq 2, \text{ }j\leq30,i<30
\end{cases}$

Anything that doesn't fall in these categories is $0$.

Now,

$\mathbb{P}(A)=\displaystyle\sum_{r=0}^{19} \mathbb{P}(A_{21,r})+\sum_{r=22}^{30} \mathbb{P}(A_{r,r-2})+\mathbb{P}(A_{30,29})$ and $\mathbb{P}(B)=1-\mathbb{P}(A)$

Playing with this code, we now answer the question that I asked above. According to the model, when both the players are equally skilled (both while serving and defending), it makes no difference as to who serves first. This seemed a counter-intuitive to me because assuming everything else equal, I thought the first player has the initiative.

Let's look at the question of serve-advantage with the following graphic.



The probability of $A$ winning the game is plotted in the Y-axes. The orange curve is when both players are equally adept at winning the rallies when they serve. That 'adept-ness' is in the X-axis. The upper blue curve is when $A$ has a 'slight' serve-advantage over $B$ and vice verse for the lower green curve. (The 'slight' is 1% here)

The green curve clearly shows the second player can 'pull-down' $A$'s chances of winning the game by developing a serve-advantage though at professional levels this diminishes fast.

Yet another interesting graphic is the one where the first player has the same probability of winning a rally irrespective of who served.


Again the Y-axis shows the probability of $A$ winning the game and the X-axis, his probability of winning the rally (irrespective of the serve). The graph pretty much says that once a player reached about 2/3rd chance of winning the rally, there is pretty much nothing more he has (or need) to do.

Hope you enjoyed this. Wish you all a very Happy New Year!!



Yours Aye,
Me