Wednesday, March 29, 2017

Calculating the size of Hyrule in Breath of the Wild

Spoiler warning: This post contains minor spoilers for The Legend of Zelda: Breath of the Wild. If you're very sensitive to spoilers, and you don't want to know anything about the map or characters or Link's abilities in the game, then don't read this.

I bought The Legend of Zelda: Breath of the Wild and I love it! One of the coolest things about it is the massive open world. There's just so much to explore, and you can have hours of fun exploring an area, only to find that it is only a tiny fraction of the whole of Hyrule, which is all entirely open to exploration. I wondered exactly how big the world is, so I made a fairly precise calculation of exactly how big the world is, in real-world units.

If I'm even going to start a task like this, I better have a frame of reference so I can relate the game world with the real world. Luckily there's this minigame in Breath of the Wild.


Branli is a researcher who is interested in learning about "bird people". (I guess he's referring to the Rito.) He is located at the top of Ridgeland Tower. Because of Link's ability to paraglide, he thinks that Link is a bird-man. If you pay him a deposit of 20 rupees, he will have you glide off the tower, and measure the distance you travel. (If you're wondering, he does pay you back if you go far enough.) Fortunately for me, the distance is measured in meters, and we can see it live, as Link is gliding.


So when I reached 500 m (actually 500.1 m but whatever), I immediately paused the game to look at the map.


Above is the map at the most zoomed out level. (I've annotated it to point out the tower and Link.) Wow, you can see that 500 meters is pretty small when compared to the whole of Hyrule! In fact, the above map can't even show the entirety of Hyrule, just the north part! I took another screenshot where the map shows the south part:


I don't like dealing with 2 images, so I used image editing magic to combine them into a single image:


Now THIS is the entirety of Hyrule. Neat! From this point, I used Web Plot Digitizer to find the total size. This cool web app lets you click on points, and it tells you their coordinates. It even scales pixels into arbitrary units, if you have a reference (which I have, thanks to Branli!).

First I uploaded my image with the entire Hyrule map. This tool can handle all sorts of plots, but I chose "Map with Scale Bar". Well, in this case there is no actual scale bar on the map, but the 500 meters between the tower and Link is effectively a scale bar.

Then I had to click 2 points to use as a scale to calibrate the axes. Here I clicked on the tower I jumped from, and on Link's current location, which is 500 meters away. Then I entered the distance and the unit. I entered it in kilometers because that's probably a better unit to measure Hyrule.


Now I can pick any number of points, and then view their coordinates in km. I chose the top left corner of the map, and the bottom right corner. The map fades out at the edges, so I tried to choose the points where the fading started.


Finally we can calculate the east-west distance and north-south distance of Hyrule by subtracting these coordinates. The width is about 10.271 km by 7.905 km. Approximately 10 km by 8 km. Amazing!

Friday, February 10, 2017

Introducing a new mathematical notation for functions

How it's usually done

I've always been quite unsatisfied with the standard mathematical notation for functions. Typically, if you wanted to define functions, you would say something like this:

I want to emphasize the difference between f and f(x), since I think it is worth noting. f represents the function, whereas f(x) represents the value you would get if you plug in x into the function. Another way of seeing this is that in this example, the "type" of f is "function", whereas the "type" of f(x) is "real number". Of course, f(x) doesn't mean anything unless you already know what x means.

So, with this in mind, you'll notice that the above notation, which was supposed to define the function f, only told us what would happen if you plugged in some number x. A real definition should have the symbol to be defined (in this example f) by itself on the left hand side, and the thing it represents on the right hand side. But here, f is not by itself on the left hand side. Since we lack the notation to say what f is, we introduce a new variable x and say what f(x) is. The implicit idea behind this is that there is only one function that transforms the input variable x into the output specified by that expression. This makes sense, but it is really an indirect workaround for the lack of actual function-definition notation.

As an (admittedly contrived) analogy, consider what we would do if we lacked the digit "5" in our notation, but we had all other digits. What if we wanted to define a number n to have the value five? We might resort to something like "Let x+1=6". Notice that this gives you enough information to know what x is, but is too indirect.

The standard way of defining functions also has some limitations of convenience. For example, it is not easily pluggable into expressions that use it. As an example, consider the function composition notation.

In case you need a refresher, function composition is when you create a new function by applying one function, and then another. In this case, the function f○g represents the result of applying g first, then f.

Let's make another analogy with numbers. Let's say you know already that a=3 and b=2. When you encounter an expression like a+b, you can replace the symbols with what they represent, resulting in the equivalent expression 3+2. Now what happens when we try this with the function composition above. We know what f and g are. But we don't have expressions for them! There's nothing we can plug in. We can try confusing f(x) with f. Then we the nonsensical notation:

It's not clear here how this should be interpreted. This is supposed to be true for all x. But if we plug in x=3, we get this weird result that has obviously lost all meaning:

Clearly, we need a better way of writing functions.

My way

I propose that we write the above function definitions like so:

Now f and g are defined directly. The function consists of curly braces with two clauses separated by a colon. The first clause introduces a temporary symbol to represent any arbitrary value in the domain, and the second clause is an expression in terms of this symbol showing the procedure of transforming the input value into the output.

If you have seen "set-builder notation" before, you might recognize it as similar to the notation that I am introducing.

In fact, the only difference is that instead of a value in the second clause of set-builder notation, there is a condition. If you view a condition as a boolean value (AKA a value that is either true/false), then a set is nothing but a function that results in a true or false value. So, these notations are compatible. If you're into set theory, you might already think of sets in your head as functions that result in booleans.

Let's see how we can plug the functions into expressions:

See how clear this is? You can see where the functions are really easily using this notation, and there is no "type confusion" between functions and numbers, so to speak.

Bonus features

Derivatives

With standard notation, you would probably write something like this:

Here, the function's independent variable is weirdly embedded within the differential operator. Also, the resulting function cannot be used in an expression. Even something like evaluating it at a x=3, which should be as simple as putting (3) at the end, is not easy. There are a few common special-purpose notations to solve this very specific issue:

But this is not required if we use my notation for functions. The derivative operator, in essence, takes a function and results in a function. So it can itself be viewed as a higher order function, let's call it D.


If you want, you can express the definition of the derivative like this:

Fourier Transform

This is how you might have seen the Fourier transform definition. It was probably explained to you in words (as opposed to math) that capital F is the transform of lowercase f.
(Note: this is the way I was taught it. It uses j as the imaginary unit, and there is no 2π in the forward transform. If you're used to a different definition, some of the properties/pairs are slightly different)

There was no good way to write a transform pair, so one was invented for that overly-specific purpose:

This notation relies on the "magic variables" t and ω to be the independent variables of the two functions.

With my notation, the Fourier transform may be expressed as a higher order function FT like this:

And a transform pair can be expressed like:

Wednesday, January 25, 2017

Generating a cube in Python

Check out this cool image!
enter image description here

I generated it with the following python code:

import numpy as np
import matplotlib.pyplot as plt
plt.imsave(
    'outfile.png',
    np.histogramdd(
        np.dot(
            np.random.random((10000000,3))-.5,
            np.array([[0.4,0],[0.1,0.4],[-0.2,0.3]])),
        bins=(500,500),
        range=((-.5,.5),(-.5,.5)))[0],
    cmap='gray')

How it works

The image consists of 10 million random 3D points which have been projected into 2D, and then turned into an image.

I start with generating 10 million random 3D points where each component can vary uniformly from -0.5 to 0.5. Notice that these points will form a 1x1x1 cube centered at the origin. This is done with the line np.random.random((10000000,3))-.5. This is a 10000000x3 numpy array.

In order to turn these 3D points into 2D points, I use an isometric projection. An isometric projection is not as realistic as a perspective projection, but it is simpler to compute. All that needs to be done is a linear projection (or an affine projection, in case you don’t want the origin to project on the origin). In this case, the center of the projected cube will be at the origin. To perform the isometrix projection, I multiply the 10000000x3 matrix of points on the right with the 3x2 matrix np.array([[0.4,0],[0.1,0.4],[-0.2,0.3]]). I chose this matrix arbitrarily, just so that the picture looks nice at the end. This now results in a 10000000x2 matrix, containing 10 million 2D points, representing a projected cube centered at the origin.

Now I have a bunch of points, but what I really need in order to make an image is a 2D array of pixel intensities. To obtain this, I used np.histogramdd, which computes a multidimensional histogram of the data we computed. Pretty much, I am partitioning the 2D space from -0.5 to 0.5 in each dimension into 500x500 “bins”, and counting how many points in each bin. Each bin will then correspond to a pixel, and the pixel intensity should be proportional to the count of its bin.

Finally, I use plt.imsave to save the image as a PNG. Neat!

Written with StackEdit.

Thursday, December 15, 2016

Heatmaps of Different Keyboard Layouts

Most people use QWERTY as their keyboard layout. I did too, until about one year ago. Over the past year, I’ve tried both Dvorak and Colemak. I’ve gotten to about 60-70 WPM on all three of these layouts, and after that I feel that typing speed doesn’t really matter much anymore—especially if I’m coding and I’m spending most of my time thinking instead of typing. But I still like Dvorak and Colemak better than QWERTY because they are more comfortable. I think I’ll stick with Colemak, since it’s more similar to QWERTY, and I want to be prepared for situations where I may be forced to use a QWERTY keyboard.
I wanted to create some visualizations to make the benefits of Dvorak and Colemak more apparent. Here are some heatmaps I generated in Python using numpy and Pillow. These are based on the frequency of letter usage (data from Wikipedia). Red corresponds to more frequently used areas, and blue corresponds to less frequently used areas.

QWERTY


Colemak

Dvorak


Pretty cool, huh? You can see that clearly, Colemak and Dvorak allow you to stay on the home row (the middle row) far more than QWERTY does. QWERTY just has your fingers going all over the place.

The math behind the heatmaps

I actually generated the pixel data for the heatmaps using my own algorithm, since I thought it would be fun. I don’t actually know how heatmaps are typically generated, but maybe it’s somewhat similar to this. I’ll explain the math I used.
So here’s the information I started with:
  • , the number of keys on the keyboard
  • for , the pixel coordinates of key
  • , the frequency of usage of key (i.e. the proportion of all letters that this letter makes up)
The goal is to assign a number to each point on the plane corresponding to the intensity of that point in the heatmap. One obvious way to go about this would be to go through each from 0 to , and then color the point with intensity —then for any remaining points, color them with intensity 0. However, this would make for a rather boring diagram, since only single hard-to-see pixels would be colored, and most of the diagram would be zeroes. So, I came up with a better way.
I needed a way for keys to color the points closer to them with a higher intensity than points farther away from them. For this, I used something similar to a Gaussian PDF. I used this formula to determine how much key should color point :

To break this down, the term represents the squared distance between the point to color and the key in question. When we multiply by -0.003 (a completely arbitrary constant that I fould worked well) and then exponentiate it, we get a term that peaks at , but then tapers off to 0 uniformly in all directions as it gets farther and farther from . Then we multiply it by , since we want more frequent keys to have more intensity than less frequent keys. I then summed these terms over all to get my final calculation:

This is what my program calculated for every point in the image. It then converted it to an appropriate RGB color, and saved the image as a PNG so that I could see it!
Written with StackEdit.

Installing Swift 3.0.2 on Ubuntu on Windows 10

I followed the instructions at the Swift download page in the Linux section. I used the “Swift 3.0.2 RELEASE - Ubuntu 14.04” download. This environment variable remembers the location where I downloaded it.

export SWIFT_ROOT=$HOME/swift

Hello world works

At this point, I can run a simple hello world program. I created a file called hello.swift with the following contents:

print("Hello world")

Then I ran it as such:

swift hello.swift

As expected, it printed hello world.

Executable stack issues

But then I found that I wasn’t able to use the package manager to build an existing Swift package called LogicSim that I created on my Mac, which worked there. When I went to that directory and ran swift build, I got the following error:

/home/anoop/swift/usr/bin/swift-build: error while loading shared libraries: libFoundation.so: cannot enable executable stack as shared object requires: Invalid argument

The fix

Apparently that error is caused by some flag in the shared object ELF file libFoundation.so. To clear it, I ran the following commands

sudo apt-get install execstack
sudo execstack -c $SWIFT_ROOT/swift/usr/lib/swift/linux/libFoundation.so

That fixed the above error, but…

Operation not permitted errors within .build folder

Now when I try swift build I get these errors

warning: minimum recommended clang is version 3.6, otherwise you may encounter linker errors.
Compile Swift Module 'LogicSim' (4 sources)
<unknown>:0: error: error opening '/mnt/c/Users/anoop/GoogleDrive/Swift/LogicSim/.build/debug/LogicSim.build/Module~partial.swiftmodule' for output: Operation not permitted
<unknown>:0: error: error opening '/mnt/c/Users/anoop/GoogleDrive/Swift/LogicSim/.build/debug/LogicSim.build/Port~partial.swiftmodule' for output: Operation not permitted
<unknown>:0: error: error opening '/mnt/c/Users/anoop/GoogleDrive/Swift/LogicSim/.build/debug/LogicSim.build/AndGateModule~partial.swiftmodule' for output: Operation not permitted
<unknown>:0: error: error opening '/mnt/c/Users/anoop/GoogleDrive/Swift/LogicSim/.build/debug/LogicSim.build/main~partial.swiftmodule' for output: Operation not permitted
<unknown>:0: error: build had 1 command failures
error: exit(1): /home/anoop/swift/usr/bin/swift-build-tool -f /mnt/c/Users/anoop/GoogleDrive/Swift/LogicSim/.build/debug.yaml

The fix

I didn’t really know why this was happening. I suspected bad permission bits in the directory, since it resides on my C: drive, inside my Google Drive folder, which was being synced from when I worked on it on my mac. I just removed the build directory and tried again:

rm -r .build
swift build

Surprisingly, the build succeeds without errors!

I also ran the executable to make sure it works as expected, and it did.

.build/Debug/LogicSim

Written with StackEdit.