Tuesday, December 16, 2014

Ruby is better than Assembly


Take two systems A and B.  A and B are identical excepting that B has a CPU that is twice as fast.

The benefits that a Ruby program running on B get vs running on A outweigh the benefits that an Assembly program running on B get vs running on A.  That is to say that Ruby receives a greater marginal utility in the change to a faster system than Assembly.

Since A and B are identical excepting their clock speed, writing a Ruby program for one takes the same amount off time and effort as it does for the other.  The same is true for Assembly.

Assembly takes more time and effort to code in than Ruby.

Computers get faster over time.  Therefore, Ruby will get better than Assembly will over time.

In addition, Assembly can't get much faster, but Ruby can and will.

Further, one can only do so much work, as there is only so much work to do.  Consider the following.  One spends a month writing a program that runs for 1 week.  Or they spend one week writing a program that runs for 6 months.  But the programmer's services aren't needed again for 1 year.  Surely they should opt to spend 1 week coding.

On the other hand, a certain amount of work needs to get done.  And Ruby is doing enough work in various domains.

Tuesday, November 11, 2014

A Better Typing Tutor

A better typing tutor

I've spent quite a bit of time doing typing tests to get better at touch typing.  2 years ago I could only type around 25-30 wpm without looking.  Today I can type around 70-80 wpm (on a good day, at least).  While a large portion of this increase is due to hard work and elbow grease, I also attribute a particular website the cause of my getting better.  This site is 10fastfingers.com.  It's a great interface for typing that is reasonably responsive, and the creator responds to feedback.  He even implemented my suggestion of being able to hide the timer (for us more anxious folk).

The main typing test gives you a random assortment of the 200 most common words in whatever language you choose.  It then gives you a minute to type out as many of that list as possible.  It's mostly lowercase and other than an occasional apostrophe, there is no punctuation.

The "advanced" test has a pool of 1000 words to randomly choose from, which contain many more occurrences of capital letters, and even some punctuation from abbreviations.

The other features of the tests are that you can only backspace in the current word, the typing area is separate from the word list, and every time you type a word, it disappears and the word in the list turn from black to either red or green depending on whether you typed it correctly.

Each of these features and their particular mixture can be different (for example, writing over the list instead of separately), but I'm not going to talk about those.

The features I am going to discuss are those of word choice/vocabulary, readability of word lists, and the computer's awareness of your skill level.

Arguably, these "features" are present in the 10fastfingers test.  For example, the word list has a readability of zero, the computer has zero awareness of your skill (in terms of using that knowledge to alter word choice), and the vocabulary is offered in 2 levels.  The vocab choice comes from there being an advanced test with 1000 word pool.

Other sites offer more readable word lists, but they suffer a different problem as a result.  Their method of offering readability comes in the form of the word list being a direct quite that a human has written somewhere.  The cost of this is maldistribution of letter frequency.  For example, in a Moby Dick quote, the letter 'w' might come up more often than on average, due to the word "whale" showing up so much.  Now, this isn't too big of a problem, but that solution forgoes another possible feature, skill awareness and word choice as a result.  If the computer knows you suck at typing "ae", it is more difficult to generate word lists if all you have to choose from are quotes.

And that brings us to the second feature I want to talk about.  The computer's awareness of your skill level.  That is, your skill at typing particular letters or letter groups.  For example, a lot of people are much more skilled in typing the letter group "the" than any other three-letter letter group because they type it so often.  Try it now!  I define "skilled" as being the amount of time in milliseconds it takes to type the letters in a letter group starting with the stroke of the first letter to the stroke of the keystroke following the last letter.  So if, say, you're typing the word "there", then the letter group "the" would be measured starting the timer at typing the "t" and stopping the timer at typing the "r".  Javascript is good at differentiating to the millisecond, and if someone were typing at 1 millisecond per character, their wpm would be around 12000, so milliseconds are good enough to measure by.

Finally there is the matter of vocabulary choice.  This is straightforward.  A vocabulary pool would grow to include words which occur less and less frequently in culture.  This is calculable several ways, from doing word occurrence analysis on books to magazines to blogs, etc.

Sentence readability is a harder problem, I grant you, but not anywhere near impossible, especially with naive solutions.  For example, one could arbitrarily generate a handful of syntaxes in a language, and, given a dictionary with sufficiently granular parts of speech, be able to generate sentences on the fly which maintain syntactic validity.  Only thing left is to remember to conjugate, though even that could be subsumed into the arbitrary syntax list.

Now, it's one thing for the computer to be aware of your skill level, but it's another thing to do anything about it.  Let's say it takes you 38 milliseconds to type the letter group "le" but it take everyone else 25 milliseconds (if we're comparing like wpm's).  In that case, the computer should opt to give you sentences in which "le" shows up more often, at least until you get better at it, or perhaps just for some temporary amount of time.  This will offer to strengthen your weakest muscle motions and even out your overall typing skill.



Monday, July 21, 2014

Mandlebrot rendering optimization method

Mandlebrot rendering optimization method

I thought of a new optimization for rendering the Mandlebrot set on a computer screen.  It involves prioritizing pixels based on whether or not their color has changed since the last iteration, and it is useful for real-time rendering.

Consider an unrendered 1,000x1,000 px canvas.  On it are 1,000,000 pixels to calculate.  The traditional naive method is to iterate over every pixel and stop only when the dwell is reached or the orbit escapes.  Such a method is computationally costly when the dwell is considerably large and there are large portions of pixels in the set (i.e. traditionally black pixels) within the current canvas.  One purpose of real-time rendering is to see just outside the set, not where the set is per se.  This new rendering method will algorithmically priorotize colored pixels to calculate in a computationally efficient manner to tend to render the bands first before spending time verifying that pixels in the set will cap out at the current dwell.

For the purposes of illustration, let us also assume that our 1000x1000 canvas is centered at the origin with horizontal and vertical ranges of [-2,2].

My optimization algorithm will start with the assumption that all pixels are in the same band, so we will only calculate one iteration of the top-left-most pixel.

This is easy to display, as the point (-2,2) escapes before the first iteration:





Next, we break down this "one" pixel into 4 sub-pixels and check to see what their color is.  As a result, you get a 2x2 Mandelbrot set render:

Next, of the pixels we just rendered, we only break them down into their subpixels if they are a different color from their parent.  So we will calculate the children of the top-right, bottom-left, and bottom-right, but ignore the top-left since it's the same color as last time.  Note that this is a naive implementation of the algorithm for illustrative purposes.  The next run gives a 4x4 render of the Mandelbrot set:



As you can see, we are already starting to see the shape of the set, and we've only calculated 13 pixels.  The next version will only select those smaller pixels whose color is different from its parent and break them down to get a 16x16 render:

As a result of selectively ignoring stagnant pixels, we can rush to render those regions which are interesting.  Now for 4 iterations this particular algorithm isn't any more impressive than if you simply rendered pixels in subchunks with no prioritizing, but this method starts to shine in areas where there are large regions of black, like a zoom-in to a mini-mandelbrot.

The details of the prioritizing process is left as an exercise to developers, but a few notes may aid the process.

1. It may be useful to only deprioritize regions for a few iterations, as seen in the example above, a naive deprioritization will lead to interesting areas being left unrendered until the end.
2. Be sure to calculate each pixel all the way to its dwell, as coupling the dwell with the current iteration in the render will result in mandelbrot set members to be focused on.

Got it working!






You can see that it very quickly finds a lot of the noisy parts of the image, and defers computation for areas which have neighboring colors that are the same.

Update:  Already got it quite a bit faster!





The big blue area is where the dwell is maxed out.