An Exclusive Integral

Calculus Level 5

The bitwise exclusive or operator " \wedge " is well-defined for all non-negative integers. We can easily extend it to the non-negative reals. Simply take two non-negative reals, x x and y y , and write each one out in binary. Line the digits up, and let z = x y z = x \wedge y like so:

x = 101.001101010100110101010011010101... x = 101.001101010100110101010011010101... y = 111.000011000011001111111111011111... y = 111.000011000011001111111111011111... z = 010.001110010111111010101100001010... z = 010.001110010111111010101100001010...

It may be the case that x x or y y have two possible representations in binary, one ending in infinite 0 0 's, the other in infinite 1 1 's. For uniqueness and therefore determinism, we choose the representation with infinite 0 0 's.


Let C C be the interior of a circle in R 2 \mathbb{R}^2 , with radius 1 2 \frac{1}{2} , and center at ( 1 2 , 1 2 ) (\frac{1}{2}, \frac{1}{2}) . Let I I as:

I = C x y d x d y I = \iint\limits_{C} x \wedge y\:dx\:dy

What is 2 20 I 2^{20} I , rounded to the nearest integer?


The answer is 411775.

This section requires Javascript.
You are seeing this because something didn't load right. We suggest you, (a) try refreshing the page, (b) enabling javascript if it is disabled on your browser and, finally, (c) loading the non-javascript version of this page . We're sorry about the hassle.

2 solutions

Jon Haussmann
Aug 31, 2014

It is easy to show that if 0 x 1 0 \le x \le 1 and 0 y 1 0 \le y \le 1 , then x y + x ( 1 y ) = 1. x \wedge y + x \wedge (1 - y) = 1.

Let I = C x y d x d y . I = \iint_C x \wedge y \: dx \: dy. Using the transformation y 1 y y \mapsto 1 - y , we get I = C x ( 1 y ) d x d y . I = \iint_C x \wedge (1 - y) \: dx \: dy. Then 2 I = C x y d x d y + C x ( 1 y ) d x d y = C ( x y + x ( 1 y ) ) d x d y = C 1 d x d y = π 4 , \begin{aligned} 2I &= \iint_C x \wedge y \: dx \: dy + \iint_C x \wedge (1 - y) \: dx \: dy \\ &= \iint_C (x \wedge y + x \wedge (1 - y)) \: dx \: dy \\ &= \iint_C 1 \: dx \: dy \\ &= \frac{\pi}{4}, \end{aligned} so I = π / 8 I = \pi/8 .

The closest integer to 2 20 π / 8 2^{20} \cdot \pi/8 is 411775.

Hah, well done. My choice of integration domain was not as tricky as it could have been, it seems.


So... hmm. I feel like I should either change the problem to have a domain of integration for which the reflection trick doesn't work, or stick the problem as-is in #Calculus, since no programming is actually required. Thoughts, anyone?


UPDATE: And I see that topic-change is now a user-accessible feature! Thank you Brilliant staff - moved this problem to Calculus.

Daniel Ploch - 6 years, 9 months ago

Yes, this is how I did it as well. Presumably everyone who solves the problem will do it this way (except the proposer :) ).

Patrick Corn - 6 years, 9 months ago
Daniel Ploch
Aug 30, 2014

The function f ( x , y ) = x y f(x, y) = x \wedge y is neither differentiable nor continuous, and has no closed form anti-derivative. Despite all of this, the function is, in fact, integrable.

Before we can make any progress, we need to get some idea of what this function looks like, at least in [ 0 , 1 ] × [ 0 , 1 ] [0, 1] \times [0, 1] . It's clear that at all such points, x y x \wedge y is bounded in [ 0 , 1 [0, 1 ), but we need to have some idea of what the distribution is like if we're going to integrate it. Here's a rendering of what the function looks like for each bit, starting with the 1 / 2 1/2 bit, then the 1 / 4 1/4 bit, and so on. The bluer a pixel is, the closer it is in value, for the acknowledged bits, to 1 1 , while the whiter pixels are closer to 0 0 in value.

Rendering Rendering

The rendering should make obvious what we can also derive analytically - that x y x \wedge y has fractal behavior on the coordinate plane. Each binary bit below 2 0 2^0 is set for exactly half of the area of [ 0 , 1 ] × [ 0 , 1 ] [0, 1] \times [0, 1] , but over increasingly finer-grained checkerboards for each bit. This enables us to answer a useful question:

0 1 0 1 x y d x d y = 1 2 ( 1 2 1 + 1 2 2 + 1 2 3 + . . . ) = 1 2 \int\limits_0^1 \int\limits_0^1 x \wedge y\:dx\:dy = \frac{1}{2}(\frac{1}{2^1} + \frac{1}{2^2} + \frac{1}{2^3} + ...) = \frac{1}{2}

More directly, we can actually compute the integral of any square in any fractal layer, by computing the minimum value of x y x \wedge y based on the square's coordinates and dimensions, and then using the geometric series we discovered to compute the total value across all remaining bits. However, the domain of integration - a circle - cannot be fully divided into exactly these fractal squares. This is okay, though, because we don't need to compute I I exactly - we just need to get it accurate to 20 20 bits.

We can borrow a technique used by cartographers here to get I I arbitrarily accurate. We can pick an n 0 n \geq 0 , divide the unit square into 2 n × 2 n 2^n \times 2^n sub-squares. For each one, we know how to compute the true integral, V V , over that square. We add a value to the total integral volume based on a simple condition for each square

  • If the square is totally within the circular domain, add V V

  • If the square is partially within, and partially without, add 1 2 V \frac{1}{2} V

  • Otherwise, add 0 0

To get 20 20 bits of accuracy, we need to ensure that the total volume of the boundary squares in our calculation does not exceed 2 20 2^{-20} . For a given n n , the approximate total volume of the boundary squares is:

1 2 π ( ( 1 2 ) 2 ( 1 2 1 2 n ) 2 ) \frac{1}{2} \cdot \pi \cdot \left( \left( \frac{1}{2} \right)^2 - \left( \frac{1}{2} - \frac{1}{2^n} \right)^2 \right)

To get this expression below 2 20 2^{-20} , n n needs to be 21 21 or greater. However, we can't evaluate 2 21 × 2 21 2^{21} \times 2^{21} squares directly - it would take days, if not weeks, to do 2 42 2^{42} calculations like that. Fortunately, we don't have to - we can, instead, recursively evaluate the unit square [ 0 , 1 ] × [ 0 , 1 ] [0, 1] \times [0, 1] , splitting it into four equal quadrants for further evaluation when the square is not strictly within or without the circle. In this way, we will make a number of calculations that is linear in the number of boundary squares, which is linear in 2 n 2^n , rendering the calculation tractable. Here's a rendering of the recursive breakdown, where red overlays are outside, green are inside, and yellow are border:

Rendering Rendering

Running the code below up through n = 21 n = 21 (R = 22 in the code) yields the answer 411775 411775 , though the error bounds cross the fractional 0.5 0.5 mark, so we can't be certain the rounded answer is correct. Running an additional step, with n = 22 n = 22 , gives us tight enough error bounds to be completely confident in the answer, 411775 \boxed{411775} .

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import java.util.ArrayList;
import java.util.List;

public class Exclusive {

    private static final int R = 24;
    private static final int P = (1 << 20);

    private static double border = 0.0;
    private static double volume(long numx, long numy, int power, int r) {
        if (r == 0) {
            double fv = fullVolume(numx, numy, power);
            border += fv / 2.0;
            return fv / 2.0;
        }

        long x2 = numx * 2;
        long y2 = numy * 2;
        int p2 = power + 1;

        List<Boolean> bools = new ArrayList<Boolean>();
        bools.add(inCircle(x2, y2, p2)); // lower-left
        bools.add(inCircle(x2, y2 + 2, p2)); // upper-left
        bools.add(inCircle(x2 + 2, y2, p2)); // lower-right
        bools.add(inCircle(x2 + 2, y2 + 2, p2)); // upper-right
        bools.add(inCircle(x2 + 1, y2 + 1, p2)); // center

        double ret;
        if (bools.stream().allMatch(x -> x)) {
            ret = fullVolume(numx, numy, power);
        } else if (bools.stream().allMatch(x -> !x)) {
            ret = 0.0;
        } else {
            double v1 = volume(x2, y2, p2, r-1);
            double v2 = volume(x2 + 1, y2, p2, r-1);
            double v3 = volume(x2, y2 + 1, p2, r-1);
            double v4 = volume(x2 + 1, y2 + 1, p2, r-1);
            ret = v1 + v2 + v3 + v4;
        }
        return ret;
    }

    private static double fullVolume(long numx, long numy, int power) {
        long num = 2 * (numx ^ numy) + 1;
        double den = Math.pow(2.0, 3*power + 1);
        return num / den;
    }

    private static boolean inCircle(long numx, long numy, int power) {
        // (x-1/2)^2 + (y-1/2)^2 < (1/2)^2
        // (nx/d - 1/2)^2 + (yx/d - 1/2)^2 < 1/4
        // (2nx - d)^2 + (2yx - d)^2 < d^2
        long x1 = 2*numx - (1L << power);
        long y1 = 2*numy - (1L << power);
        boolean ret = (x1*x1 + y1*y1) < (1L << 2*power);
        return ret;
    }

    public static void main(String[] args) {
        for (int r = 1; r <= R; r++) {
            border = 0.0;
            double v = volume(0, 0, 0, r);
            System.out.println(v * P + " +- " + border * P);
        }
    }

}

That soultion... like a boss.

Ilya Andreev - 6 years, 4 months ago

Awesome idea and nice animations. Can you share the code for your animations?

Agnishom Chattopadhyay - 4 years, 2 months ago

0 pending reports

×

Problem Loading...

Note Loading...

Set Loading...