Tuesday, November 24, 2009

Coding in my spare time now feels so blah

So I started work at my job for the Summer just over two weeks ago, which is great, I'm really enjoying it, but it has almost completely removed my motivation in my spare time. When I'm working all day coding, I really can't be bothered to do more at home, well at the moment at least. Though I have been quite busy lately and that could've been contributing to it.

Having used python almost exclusively at work so far, I'm really enjoying it, it seems to be a really nice programming language, and if I do go back to working on my project, I'll be sorely tempted to start again in python. Though I don't really know how to use its gui libraries, and I doubt I'll get any chance at that at work.

The other thing I find really annoying is that after getting used to my large, wide screen monitor at work, it's really frustrating to use eclipse with my small laptop screen. Though that's a fairly minor thing really.

Tuesday, November 3, 2009

Dimetric Land Rendering

So I got started on my game, I'm calling it BMAC (Build me a city). I've been playing around with the dimetric rendering (sort of like isometric, except instead of all 3 angles between the axes being the same, 2 are the same, and the third is different). I've got it to the point where with a grid of tiles, each with an elevation, it's drawing a fairly nice landscape. Without further ado I present to you my test picture.

As you can see, it's not quite perfect, some of those little moundy things should really merge with their neighbours, and at the top of the hill in the bottom two lines stick out a bit which is odd, but I plan on doing them soon.

That was quite a bit of effort, and quite a bit of drawing pictures to see how it should look. I plan on making it so it can draw from 4 directions looking down at it, but have only down one of these so far, the rest will come.

That's around 500 lines of code or so, which is less than I thought it'd be, but I suppose once I get all the special cases and directions and things that'll increase significantly. I'm quite chuffed though, I thought that would take much longer.

Monday, September 21, 2009

Yous

This is a word I find myself saying more and more. In current usage, the word you does not technically have a plural, but yous (and also you all) are becoming popular for that. I find myself saying it without thinking, and when I try not to say it, it sounds wrong. It's funny the way languages change.

I'm still not sure whether I want to try and stick with the more "correct" usage, or go with this new plural form. Generally I try and use proper grammar as much as possible, but there really isn't all that much point in casual usage. Words come in and out, meanings change, but sometimes it can be fun to go against that change. I still enjoy asking people, "Contemporary with what?" when they use the term contemporary to mean recent, because that's not its actual meaning. Most people don't even understand what I'm on about, sad as it may be. Ah well, I shouldn't spend too much time bemoaning this change, as I said, languages do change, and will keep changing.

Saturday, September 19, 2009

Welcome To The Masquerade

I bought Thousand Foot Krutch's new album on Monday, and it's awesome! Wasn't even all that long I had to wait to be able to get it here after the US release, less than a week which is much better than the about 2 weeks I had to wait for The Flame In All Of Us (TFIAOS). I had really been looking forward to this, the promotion TFK did for it, the teasers and all really had me hooked, though it's much better hearing it as the entire album than the few songs they had released.

The album just works so nicely as an album, the songs fit together, the sound is fairly consistent without being all the same. And it's heavier, much heavier than TFIAOS, which I like. I'm not sure whether in ranks above Phenomenon as my favourite TFK album (and favourite album of any band), but if it doesn't it comes close.

My favourite song on it (at least for the moment) is E for Extinction. It has a great quiet - loud - quiet sound which is always good, and a good message to go along with it. I particularly like the lyric When we move we camouflage ourselves. We stand in the shadows waiting. Which really hit me. I also like the song The Part That Hurts The Most (Is Me). Which also sounds great and has some good, hard hitting lyrics which I think is a must. I can never get too into a song with poor lyrics.

So well done TFK, you did a great job making an excellent album! Now come back to NZ.

Thursday, September 3, 2009

Laplace's Equation in 3D, polar coordinates

The title basically says it all. For a mere three marks (out of 50) in our take home test, we've been asked to Laplace's Equation in spherical coordinates. As you can see from that post it's a mission. I basically gave up around half an hour ago. It seems that I made a mistake when I was inverting the Jacobian (2 pages of working), which is a slightly different way from the linked article, but that's how we've been asked to do it. Tomorrow I suppose I'll go through it and find my error, which will be tedious. I did get maple to do it for me, so I know what I should get, and I was pretty close, but it appears I messed up one column.

The frustrating part is that even when I've inverted the matrix, I still need to do the ridiculous substitutions you see near the bottom of that page. I won't do them all at once like that, I'll be a bit smarter, but still, it's going to be tedious.

The thing that's really annoying is not that this is particularly hard - it isn't, it's just tedious and a huge amount of work. I won't be surprised if this question goes to 4+ pages. And it's not the kind of work you have to do by hand any. That's why people developed computer algebra systems, why we rely on the work of people who have gone before us, so we don't have to sit there doing tedious calculations. However, I do understand the point, so I'll strive to do it well, plus I want a good mark in this paper, and the test is worth 20% so it is fairly important. Maths Away!

Wednesday, August 26, 2009

Playing with Qt Jambi

Over the last couple of days I've been playing around with Qt Jambi, the Qt bindings for Java, which are pretty cool. I haven't used them that much so far, but they seem really nice. I'd been starting to write this little car game thing, which is more a proof of concept at the moment, which I've now ported to be able to use Qt.

Try it as an applet here (note this is using ordinary Java swing, not Qt as I'm not sure if you can embed a Qt widget in an Applet (or in any AWT or swing element). Then there'd be the trouble of having to download Jambi which is fairly big.

Use your arrow keys to drive around, Ctrl+R resets (in hindsight, not a good choice as it coincides with firefox's and epiphany's reload page shortcut (possibly other browsers too)). The physics is terrible, but I find it fun just driving around, making pretty patterns. You might need to click the applet to give it focus.

Or you can download it here. That includes the source. To run it using qt, it will need to find the Jambi jar file, and it looks in the current directory and "/usr/share/java/qtjambi.jar" (the latter is the default location in Ubuntu (and possibly other distros), so you just need to install the jambi package). You can download Qt Jambi here. Then you need to pass the command line option '--qt'. By default I try and use opengl (which is faster), if it doesn't seem to work, try '--qt --no-gl' to use the regular qt rendering engine.

The number in the top right corner is how many milliseconds it's taking to draw each frame (averaged over the last 100 frames I think). I found Qt with no opengl to be about the same speed as Java swing at 640x480, which I found surprising, I thought Qt would be significantly faster, though at full screen swing slows right down, while Qt only takes a little bit longer, and with opengl it's about 25% faster. YMMV.

I had to be a bit sneaky when writing this so that the swing version would run fine even without the Qt libraries. My first (which I thought was nicer) implementation didn't work, as there were references to the Qt classes in the classes that were being run, even though they weren't used. So when I redid it I had to split everything up, a swing version and a Qt version, so that when swing was being used there would be no references to the Qt classes. I wasn't sure that that would work, but it did, which is pretty cool. Enjoy.

Edit: It appears it's pretty hard for this thing to regain focus, I should probably look into that, enjoy it if you can get it to work, otherwise download the jar, that's more likely to work correctly.

Tuesday, August 25, 2009

Windows Network Grrr...

I've come to be incredibly frustrated with how networks work under Windows (XP) over the past year or so. I'll explain my set up a little first, I have a laptop which runs Ubuntu, I connect to the Internet via another computer (running Windows XP) which connects directly to our cable modem. I thought I'd have issues with this seeing as how I wasn't using Windows, but on my side it has been a breeze (much easier than in Vista on the same laptop).

The thing that irritates me is that every time the driver, firewall etc. is updated, or just at random other times, the computer stops me from connecting. I haven't changed anything on my laptop, I just can't connect to the network. So far we've managed to fix the problem by changing some option somewhere on the XP computer, in some nested dialog box, or whathaveyou after trying various things for around an hour. As I said earlier, it's incredibly frustrating. A thing like that should just work, which it does in Ubuntu, but not in XP (though I haven't tried the other way around). Rant over.

Thursday, August 6, 2009

The magic that's coming to your browser

I was reading on slashdot an article (actually it's more a blog) about some of the cool things that people can now do with javascript and HTML5 and the like in newer browsers. (Sorry if you're using IE, there may be new versions, but they don't support a lot of this stuff.

Have a look for yourself at some of these:

All of these are pretty cool, and note that they don't need any browser plugins to run (though some of them use external scripts, which is kind of like a plugin). I'll draw your attention to the last one in particular, notice that it doesn't use HTML, but the main page is an svg. People have been talking about how this could be the future of the web (though IE doesn't support svg at all yet AFAIK, so if it will be, it'll be a long time away). You may know of svg as a vector graphics format, wikipedia uses it quite a lot for graphs and things nowadays, where it is inherently better than standard images with pixels and all that, but it is a whole lot more than just a vector graphics format, which is why most browsers haven't fully implemented it yet (it's a whole pile of trickiness).

This could also potentially displace flash, which I'm a bit ambivalent about. At the moment I see some places where flash is used well, but all too many where it is used poorly, and the same could be done with these kind of technologies. Also, flash is a whole lot more mature that this, so it can do a whole lot more at the moment (you may have noticed the above could be quite CPU intensive), but there is good competition in the browser space so these should improve rapidly.

I hope you enjoyed my plagiarism of a slashdot article, and a bit of inane ramble.

Probably

When people ask me if I can do something, if I can come to something, etc. and I think I can and want to, my general response if 'probably.' This must infuriate some people who want to know things for "sure" and be able to plan. But I have good reasons for saying probably over definitely, sure, etc. in that it's impossibly to mean something like definitely, or sure when you're ntalking about the future. Anything could happen. And while my level of commitment is generally above the level usually referred to by probably, I can't think of a succinct way that I could say it more precisely.

In emails and things like that, I will sometimes say "Yes, barring some exceptional circumstance" or the like, but that's a bit of a mouthful in a conversation. "Almost certainly" is pretty good, but then I have to go through this whole thing when they ask me why I'm just "almost."

Oh, the tedium of trying to be precise...

Tuesday, July 21, 2009

RIP Marcoland

One week ago, the game I had been playing for a ridiculously long time went the way of the moa. I signed up to Marcoland back in 05, when I was in Japan, in November if I remember rightly. That's 3 and a half years ago - about a sixth of my life, crazy to think I played it for so long. In that time it was one of the things I'd do on the Internet every day, and I would hate to think the amount of time I spent there.

It was a MMORPG (Massively Multiplayer Online Role-Playing Game), you spent your time increasing your stats. There were also towns (the ML version of clans/guilds/etc), which would have wars with each other, a daily arena, a pvp system, and a whole bunch of other things. But, as with virtually all games of this type it got pretty repetitive, and if it hadn't been for the community there, in towns, in chat, in the forums, I'm sure I would've left a lot sooner. It was one of those games where you could play it in 5 minutes, or spend however much longer than that you wanted to there. And it was completely free, you couldn't get any advantages by donating (just nice things like a coloured name, an avatar, no ads, a custom emoticon, etc).

It's weird to think that it's gone, but I'm fairly sure it won't be back, at least not permanently that is. I've been finding I have a lot more free time so it's probably a good thing. I'd thought about quitting for a while for that very reason. I remember the day the site went down, a week ago now, I got on my computer, finished doing the other things I do on the net, and then was like, what do I do now?

I quite enjoyed the game though, it appealed to me in a number of ways. Firstly, it was a long term game, it involved a lot of planning. It also gave you a lot of stats, which I always like going through. I even programmed a few things for it, like a simulator to simulate the training beach to figure out what monster would be best to fight, a town war visualiser thing (which I never finished) and a little script-like thing that would parse the rankings pages to list players with the most protection.

The in game chat room was almost certainly the place I wasted the most time. I didn't start using this until I had been playing for about a year (or so, can't remember exactly), but I spent so much time there. Met a bunch of people - who I'll sadly lose contact with now. I had something like 80,000 chat lines I think. Which is sick. All that time lost. I was even a chat mod for a few months before the end.

I was pretty strong as a player goes, about 100th in terms of total stats, and about 30th in terms of stats/age (which gave a fairer reflection of how well younger players were doing). I would've been better than this but I didn't play so well at first, but I made up a lot later.

So would it have been better if I had never started playing? I reckon no. All in all I reckon the time I spent playing was a positive. It helped me out I reckon, and there'll be people I'll try to not lose contact with. It was something that was always with me, and would often cheer me up when I wasn't feeling so great. I don't want to play another similar game though, because I know how much time it takes, and would prefer to spend the time studying, or out in the world with friends, or whatever.

Anywho, good bye Marcoland, you were good while you lasted. And thanks Marco, thanks for all you gave to the players of ML.

Saturday, July 18, 2009

String Permutations II

I thought of a few ways I could optimise the permutation routines from yesterday, which were relatively simple, so I thought I'd try them out. I'm always interested in ways I can make code faster, and enjoy testing things like this out. Most of the improvements this time round were to the iterative method:
 1: public static List<String> getAllPermutationsIteratively(String s) {
 2:    int length = s.length();
 3:    if(length <= 1) {
 4:       return Arrays.asList(s);
 5:    }
 6: 
 7:    int numPermutations = factorial(length);
 8: 
 9:    List<String> permutations = new ArrayList<String>(numPermutations);
10: 
11:    for(int permNo = 0; permNo < numPermutations; permNo += 2) {
12:       char[] charsLeft = s.toCharArray();
13:       
14:       int size = length;
15:       
16:       char[] charArray = new char[length];
17:       
18:       int i, factorialSize = factorial(size);
19:       for(i = 0; i < length - 2; i++) {
20:          // The division means that the index only increases after so many iterations
21:          // The remainder reduces the number range to the number of iterations the index stayed
22:          // the same for in the previous division
23:          int factorialSizeMinusOne = factorial(--size);
24:          int index = (permNo % factorialSize) / factorialSizeMinusOne;
25:          factorialSize = factorialSizeMinusOne;
26:          
27:          charArray[i] = charsLeft[index];
28:          
29:          // Copy all elements from (index+1) onwards back one place, i.e. remove the element at
30:          // index. Note that size was decremented earlier.
31:          System.arraycopy(charsLeft, index+1, charsLeft, index, size - index);
32:       }
33:       
34:       charArray[i] = charsLeft[0];
35:       charArray[i + 1] = charsLeft[1];
36:       permutations.add(new String(charArray));
37: 
38:       charArray[i] = charsLeft[1];
39:       charArray[i + 1] = charsLeft[0];
40:       permutations.add(new String(charArray));
41:    }
42:    return permutations;
43: }
I got a new source code to html formatter by the way which I think gives better results. The first change isn't for performance, but just ensures it works properly for strings of length 0 (they could just as well throw an exception) and 1, which would've worked in my old iterative version, but not in my old recursive version (I think).

Next, I changed the loop so it increments by two each time, and did the final two letters e.g. AB and BA manually, which was a big performance improvement. The next one was saving the calculated factorial values, which saves one factorial calculation through iteration of the inner loop, which is again nice. I tried various ways of making this faster, but couldn't make it faster than it is here. Then instead of using an ArrayList of Characters, I changed it to use an array of chars, which performs better, but is a little trickier. This brought the speed of this version to be roughly equivalent to the recursive version.

Now I changed the recursive version to:
 1: public static List<String> getAllPermutationsRecursively(String s) {
 2:    int length = s.length();
 3:    if(length <= 1) {
 4:       return Arrays.asList(s);
 5:    }
 6: 
 7:    List<String> permutations = new ArrayList<String>(factorial(length));
 8: 
 9:    char[][] charArray = getAllPermutationsRecursively(s.toCharArray(), length, length - 1);
10:    for(int i = 0; i < charArray.length; i++) {
11:       permutations.add(new String(charArray[i]));
12:       charArray[i] = null; // Let the gc be able to clear this up
13:    }
14: 
15:    return permutations;
16: }
17: 
18: // length is the length if the original String
19: // pos is the current position in the char[] which a character will be added to. On the first
20: // call of this it should be one less than length
21: private static char[][] getAllPermutationsRecursively(char[] chars, int length, int pos) {
22:    char[][] toReturn = new char[factorial(pos + 1)][];
23: 
24:    // Though the == 1 case is simpler, it's faster if this is the base case
25:    if(chars.length == 2) {
26:       // There are two combinations, [0, 1] and [1, 0]
27:       toReturn[0] = new char[length];
28:       toReturn[1] = new char[length];
29: 
30:       toReturn[0][0] = toReturn[1][1] = chars[1];
31:       toReturn[0][1] = toReturn[1][0] = chars[0];
32:    } else {
33:       int toReturnPos = 0;
34:       for(int i = 0; i < chars.length; i++) {
35:          char c = chars[i]; // The current char
36: 
37:          // Make a copy of the array without c in it
38:          char[] newChars = new char[chars.length - 1];
39:          System.arraycopy(chars, 0, newChars, 0, i);
40:          System.arraycopy(chars, i + 1, newChars, i, chars.length - i - 1);
41: 
42:          // Add c to each of the returned arrays of chars
43:          for(char[] charArray : getAllPermutationsRecursively(newChars, length, pos - 1)) {
44:             charArray[pos] = c;
45:             toReturn[toReturnPos++] = charArray;
46:          }
47:       }
48:    }
49:    return toReturn;
50: }
This one only has a couple of minor changes, nothing major, it seems I did it pretty well the first time.

While doing this process I burnt my fingers a little with relatively shoddy benchmarking. At first I was getting wildly erratic results, even though I would run each version say 5 times, the time would vary by 50% (or more) between runs, which I thought was pretty crazy. The first thing I thought of doing to combat this was set my cpu governor to performance rather than dynamic, which means that it'll sit at full speed all the time, rather than throttling down. This made a remarkable difference, it seems there was a bit of lag in it going to full speed. I also have backround programs running, which you shouldn't really, but as I only run this in one thread, it shouldn't make too much of a difference.

The second main thing was that the JVM wasn't getting enough memory, so the one running second would run slower as the gc would run a lot more. By setting the starting and finishing memory to 512 MB (more than it should need, but I wanted to be on the safe size), I eliminated this discrepancy to a large degree. This also speed up the speed of execution by as much as two times, which is pretty remarkable. What brought this to my attention was running on "PARTICLEX" it would crash with an out of memory error when I changed the code and ran the iterative version first. It must've been right on the cusp of running out of memory before.

For a bit of analysis - the performance of the two in terms of speed is very close now. However in terms of memory, the iterative version should use less, but after the couple of changes I made to the recursive one that shouldn't be too bad. The iterative version is slightly shorter, so would probably get a slight preference by me, but hey. (Not that I can see any practical purpose for this).

Friday, July 17, 2009

String Permutations

Apparently the "Challenge" in the COMP102 assignment was to write some code to print out all the permutations of a string. (Say for ABC, that'd be ABC, ACB, BAC, BCA, CAB, CBA). However that challenge was apparently left over from last year, and due to the number of points of the paper changing, they haven't covered recursion yet. So I got challenged by a friend to write a program that did this without using recursion (which is the natural way I would do it).

I puzzled over this for a while, trying a couple of ways, with little success. Then I went to a tutorial for another paper, but didn't really pay much attention, more trying to figure out a solution for this problem. I made a little bit of progress, but the solution I implemented when I got back to the lab didn't work. But then I had a bit of a brain wave as I was working and managed to do it. Here's the code:
  1: public static List<String> getAllPermutationsIteratively(String s) {
  2:    int length = s.length();

  4:    List<Character> chars = new ArrayList<Character>(length);
  5:    for(char c : s.toCharArray()) {
  6:       chars.add(c);
  7:    }

  9:    int numPermutations = factorial(length);

 11:    List<String> permutations = new ArrayList<String>(numPermutations);

 13:    for(int permNo = 0; permNo < numPermutations; permNo++) {
 14:       List<Character> charsLeft = new ArrayList<Character>(chars);

 16:       char[] currentString = new char[length];

 18:       for(int i = 0; i < length; i++) {
 19:          int index = (permNo % factorial(charsLeft.size())) / factorial(charsLeft.size() - 1);
 20:          currentString[i] = charsLeft.remove(index);
 21:       }

 23:       permutations.add(new String(currentString));
 24:    }
 25:    return permutations;
 26: }
Line 19 contains the magic statement. I commented this as, "The division means that the index only increases after so many iterations. The remainder reduces the number range to the number of iterations the index stayed the same for in the previous division." I don't know if that helps all that much, but if you write down a table (which I can't be bothered doing) it makes a lot more sense what's happening. (Or get it to process "0123" or "01234" and print out each string in the resulting list)

I then wondered how this would compare to a recursive implementation, so did one of those too:
  1: public static List<String> getAllPermutationsRecursively(String s) {
  2:    int length = s.length();

  4:    List<String> permutations = new ArrayList<String>(factorial(length));

  6:    for(char[] c : getAllPermutationsRecursively(s.toCharArray(), length, length - 1)) {
  7:       permutations.add(new String(c));
  8:    }

 10:    return permutations;
 11: }

 13: private static char[][] getAllPermutationsRecursively(char[] chars, int length, int pos) {
 14:    char[][] toReturn = new char[factorial(pos + 1)][];

 16:    if(chars.length == 2) {
 17:       toReturn[0] = new char[length];
 18:       toReturn[1] = new char[length];

 20:       toReturn[0][0] = toReturn[1][1] = chars[1];
 21:       toReturn[0][1] = toReturn[1][0] = chars[0];
 22:    } else {
 23:       int toReturnPos = 0;
 24:       for(int i = 0; i < chars.length; i++) {
 25:          char c = chars[i];

 27:          char[] newChars = new char[chars.length - 1];
 28:          System.arraycopy(chars, 0, newChars, 0, i);
 29:          System.arraycopy(chars, i + 1, newChars, i, chars.length - i - 1);

 31:          for(char[] charArray : getAllPermutationsRecursively(newChars, length, pos - 1)) {
 32:             charArray[pos] = c;
 33:             toReturn[toReturnPos++] = charArray;
 34:          }
 35:       }
 36:    }
 37:    return toReturn;
 38: }
Despite this being a little longer, conceptually I think it's much simpler. (Yes, I did strip out the comments to be annoying). It's not the first version I wrote, but rather as optimised as I could be bothered doing, making it much faster than my original naive implementation.

This version turns out to be more than twice as fast as the iterative version. The two main reasons for this are that the iterative version copies, then removes the elements of a List copy of the chars in the string for every string returned, and it also does a whole lot of remainder and division operations.

Oh yeah, if you're wondering this is my factorial function:
  1: private static int factorial(int n) {
  2:    int factorial = 1;
  3:    for(int i = 2; i <= n; i++) {
  4:       factorial *= i;
  5:    }
  6:    return factorial;
  7: }
I tried a few versions, including saving each value to a list, then an array so they wouldn't have to be calculated again, and having the first 10 values precalculated, but these were slower, so I went back to this implementation. It's probably got something to do with the way the compiler optimises it.

The other thing to note with this implementation is that there is a maximum length for the string. Say the length of the input string is n, then n! must be less than 2^31 (the maximum value of an int) otherwise the arrays cannot be made big enough to fit all the permuatations. This means you can use words at most 12 letters long. In practice, I only got it to work for strings of length 10 or less. I ran out of stack space, even when allocating 2500 MB for a 11 letter word. It wouldn't let me set the memory to 3000 MB or higher for some reason.

This shows I'm up to the COMP102 challenge. Boy is that satisfying.

Consecutive Heads

In the extremely advanced statistics paper I'm doing (STAT131), our lecturer mentioned something about consecutive heads (or tails) on a coin toss. Saying that the series T, HT, HHT, HHHT, ... is theoretically infinite. Which is true. But in practice your sequence of heads is going to be relatively short.

To prove this I wrote a little Java program that would calculate these chains using the built-in pseudorandom number generator. After I got this working, I ran it for an hour on one of the uni computers. For the 80 billion trials it did, the longest chain was only 36. That's pretty short really. (I don't think the non-randomness of the pseudorandom number generator would've had any significant effect). Evaluate 2^36 and you get 70 billion (to 1 significant figure), so this was basically as expected, a chain of length 36 is a one in 70 billion chance. That's a (relatively) huge number really.

Just for fun I reimplemented my program in C, which made it about 20% faster, which is about what I expected. (Actually, it was slower on a multicore computer as I multithreaded the Java version, but I don't know how to write threaded programs in C). Anyways, that was my interesting experiment for Tuesday (when I did it).

Saturday, July 11, 2009

Grrr... blog issues

I just had some annoying blog issues when making that last entry.

Firstly, not all my bits of LaTeX code would show, I think it's because some of them were too long. So I made my own images and uploaded them. That's why some of the images look a little different to the others (I reckon they look better as they seem to have better anti-alisaing.

Secondly, to try and solve the above problem, and the fact that a number of the images were too wide for my blog, I started hacking at the template. Since some of the backgrounds were images, I had to download them and make them wider for myself. Blogger uses picasa by default for images, which is really annoying for getting a direct link, normal size, to an image, and it doesn't seem to have any regular way of providing the links, there seem to be almost random character combinations in the url. So I gave up on this and as you can see, I don't use images in the background of the main areas (there still are a few images in other places, but I think I'll keep them). I did get the template working alright though, it'll probably change some more in the near future.

By default, blogger automatically puts html breaks in where you have line breaks in the input area. This was messing me up a little so I turned this off. Blogger then goes and decides to apply this retrospectively, breaking all my previous posts so I had to go and fix them, lucky this blog is pretty new and there were less than 30... I think this way will be an improvement for the future though, it gives me more flexibility when writing and lets me practise my html more.

Grrr...

Friday, July 10, 2009

Solving the Schrödinger equation for the hydrogen atom

When I was studying for my quantum physics exam on Wednesday before last, this struck me as very elegant, albeit rather long and difficult. I had worked through it by hand, as I like doing that when I study as just reading doesn't make things sink into my brain, so I thought I'd put these notes up here, for anyone who's interested (plus, I like playing in LaTeX).

Think of when this was first done, Schrödinger was trying to see if his equation would fit in with observed phenomena, things known at the time, so he initially solved it for the hydrogen atom, which was known. Not any of these infinite square wells, harmonic oscillators, etc. you start with nowadays, as only recently have we become able to observed the effects of these.

So prepare yourself for a whole lot of maths, with a little physics woven in between.

Time-independent Schrödinger equation in spherical coordinates

So we start off with the time-independent Schrödinger equation (in 3D):

$$ - \frac{\hbar^2}{2m} \nabla^2 \psi + V \psi = E \psi$$

In spherical coordinates, the Laplacian becomes (according to wikipedia (therefore true) and other places):

$$ \nabla^2 = \frac{1}{r^2} \frac{\partial}{\partial r} \left( r^2 \frac{\partial}{\partial r} \right) + \frac{1}{r^2 \sin \theta} \frac{\partial}{\partial \theta} \left( \sin \theta \frac{\partial}{\partial \theta} \right) + \frac{1}{r^2 \sin^2 \theta} \left( \frac{\partial^2}{\partial \phi^2} \right)$$

Thus the time-independent Schrödinger equation becomes:


First, look for separable solutions of the form $$ \psi \left( r, \theta, \phi \right) = R \left( r \right) Y \left( \theta, \phi \right)$$, which gives:

equation

Now, if the potential, $$ V$$ only depends on $$ r$$ then the first of these square brackets only depends on $$ r$$ and the second only depends on $$ \theta$$ and $$ \phi$$. Thus they must both be equal to a constant, lets call this $$ l \left( l + 1 \right)$$ (because I like being difficult), so:

$$\begin{aligned} \frac{1}{R} \frac{d}{d r} \left( r^2 \frac{d R}{d r} \right) - \frac{2mr^2}{\hbar^2} \left( V - E \right) &= l \left( l + 1 \right)\\ \frac{1}{Y} \left[ \frac{1}{\sin \theta} \frac{\partial}{\partial \theta} \left( \sin \theta \frac{\partial Y}{\partial \theta} \right) + \frac{1}{\sin^2 \theta} \left( \frac{\partial^2 Y}{\partial \phi^2} \right) \right] &= -l \left( l + 1 \right)\end{aligned}$$

The Radial Equation

The first of the above two equations can be simplified by letting $$ u \left( r \right) = r R \left( r \right) $$. Now:

$$\begin{aligned} \frac{du}{dr} &= R + r \frac{dR}{dr} \\ \mathrm{and\ so\quad} \frac{dR}{dr} &= \frac{\frac{du}{dr} - R}{r} = \frac{\frac{du}{dr} - \frac{u}{r}}{r} = \frac{r \frac{du}{dr} - u}{r^2} \\ \mathrm{thus\quad} \frac{d}{d r} \left( r^2 \frac{d R}{d r} \right) &= \frac{d}{d r} \left( r \frac{du}{dr} - u \right)\\ &= \frac{du}{dr} + r \frac{d^2 u}{dr^2} - \frac{du}{dr}\\ &= r \frac{d^2 u}{dr^2}\end{aligned}$$

Now subbing into the earlier equation:

$$\begin{aligned} \frac{1}{R} \frac{d}{d r} \left( r^2 \frac{d R}{d r} \right) - \frac{2mr^2}{\hbar^2} \left( V - E \right) &= l \left( l + 1 \right)\\ \frac{r}{u} r \frac{d^2 u}{dr^2} - \frac{2mr^2}{\hbar^2} \left( V - E \right) &= l \left( l + 1 \right)\\ \frac{d^2 u}{dr^2} - \frac{2m}{\hbar^2} u \left( V - E \right) &= \frac{l \left( l + 1 \right)u}{r^2}\\ \frac{\hbar^2}{2m} \frac{d^2 u}{dr^2} - u \left( V - E \right) &= \frac{\hbar^2}{2m} \frac{l \left( l + 1 \right)u}{r^2}\\ - \frac{\hbar^2}{2m} \frac{d^2 u}{dr^2} + \left( V + \frac{\hbar^2}{2m} \frac{l \left( l + 1 \right)}{r^2} \right) u &= Eu \end{aligned}$$

That looks pretty familiar, doesn't it?

Hydrogen Atom

Now that the basis is there, we can actually start looking at stuff specific to the hydrogen atom. Firstly, the potential energy function is Coulomb's law:

$$ V \left( r \right) = - \frac{e^2}{4 \pi \varepsilon_0} \frac{1}{r}$$

Subbing this into the radial equation derived above gives:

$$ - \frac{\hbar^2}{2m} \frac{d^2 u}{dr^2} + \left( - \frac{e^2}{4 \pi \varepsilon_0} \frac{1}{r} + \frac{\hbar^2}{2m} \frac{l \left( l + 1 \right)}{r^2} \right) u = Eu$$

Now let $$ k = \frac{\sqrt{-2mE}}{h}$$, which is, of course, real as we're looking at the bound states, so $$ E < 0$$. Manipulating the radial equation gives:

$$\begin{aligned} - \frac{\hbar^2}{2mE} \frac{d^2 u}{dr^2} + \left( - \frac{e^2}{4 \pi \varepsilon_0} \frac{1}{r} \frac{1}{E} + \frac{\hbar^2}{2mE} \frac{l \left( l + 1 \right)}{r^2} \right) u &= u\\ \frac{1}{k^2} \frac{d^2 u}{dr^2} + \left( - \frac{e^2}{4 \pi \varepsilon_0} \frac{1}{r} \frac{1}{E} \frac{k^2}{k^2} - \frac{1}{k^2} \frac{l \left( l + 1 \right)}{r^2} \right) u &= u\\ \frac{1}{k^2} \frac{d^2 u}{dr^2} + \left( \frac{e^2}{4 \pi \varepsilon_0} \frac{1}{r} \frac{2m}{\hbar^2} \frac{1}{k^2} - \frac{1}{k^2} \frac{l \left( l + 1 \right)}{r^2} \right) u &= u\end{aligned}$$

$$ \frac{1}{k^2} \frac{d^2 u}{dr^2} = \left( 1 - \frac{m e^2}{2 \pi \varepsilon_0 \hbar^2} \frac{1}{r} \frac{1}{k^2} - \frac{1}{k^2} \frac{l \left( l + 1 \right)}{r^2} \right) u$$

This isn't looking very good, so lets try another substitution, $$ \rho = kr$$ and $$ \rho_0 = \frac{me^2}{2 \pi \varepsilon_0 \hbar^2 k}$$. With these, $$ \frac{d^2u}{dr^2} = \frac{d^2u}{d\rho^2} \frac{d^2\rho}{dr^2} = \frac{d^2u}{d\rho^2} \frac{1}{k^2}$$, so we get:

$$ \frac{d^2u}{d\rho^2} = \left(1 - \frac{\rho_0}{\rho} + \frac{l \left( l + 1 \right)}{\rho^2} \right) u$$

This looks a whole lot simpler, but is still not easy to solve. We'll try breaking off the behaviour of $$ r$$ and thus $$ \rho$$ tends to 0 and $$ +\infty$$.

$$ \lim_{\rho \to +\infty} \frac{d^2u}{d\rho^2} = u$$

with solution:

$$ u \left( \rho \right) = A e^{-\rho} + B e^{\rho}$$

and (assuming $$ l \neq 0$$):

$$ \lim_{\rho \to 0} \frac{d^2u}{d\rho^2} = \frac{l \left( l + 1 \right)}{\rho^2} u$$

Unlike the previous equation, the solution to this isn't well known (at least to me), but can be easily solved by the power series method. Propose a solution, $$ u = \sum_{n=-\infty}^{+\infty} a_n \rho^n $$. This has derivatives:

$$ \frac{du}{d\rho} = \sum_{n=-\infty}^{+\infty} n a_n \rho^{n-1} \quad \mathrm{and} \quad \frac{d^2u}{d\rho^2} = \sum_{n=-\infty}^{+\infty} n \left( n - 1 \right) a_n \rho^{n-2}$$

Subbing these into the differential equation gives:

$$\begin{aligned} \sum_{n=-\infty}^{+\infty} n \left( n - 1 \right) a_n \rho^{n-2} &= \frac{l \left( l + 1 \right)}{\rho^2} \sum_{n=-\infty}^{+\infty} a_n \rho^n \\ \sum_{n=-\infty}^{+\infty} n \left( n - 1 \right) a_n \rho^{n-2} &= l \left( l + 1 \right) \sum_{n=-\infty}^{+\infty} a_n \rho^{n-2}\end{aligned}$$

Which is only true when $$ n \left( n - 1 \right) = l \left( l + 1 \right) $$, $$ n = l + 1, -l $$. So all other $$ a_n$$ must be zero, giving the solution:

$$\begin{aligned} u \left( \rho \right) &= a_{l+1} \rho^{l + 1} + a_{-l} \rho^{-l} \\ &= C \rho^{l + 1} + D \rho^{-l}\end{aligned}$$

Now if you're anything like me, you'll want to double check this, so lets do that now:

$$\begin{aligned} \frac{du}{d\rho} &= \left(l+1\right) C \rho^l - l D \rho^{-l-1}\\ \frac{d^2u}{d\rho^2} &= l \left(l+1\right) C \rho^{l-1} - \left(-l-1\right) l D \rho^{-l-2}\\ &= l \left(l+1\right) \left( C \rho^{l-1} + D \rho^{-l-2} \right)\\ &= \frac{l \left(l+1\right)}{\rho^2} u\end{aligned}$$

So yep, this is a solution (well, family of solutions). However, as $$ r$$ and correspondingly $$ \rho$$ tends to zero, the second term tends to infinity, so $$ D$$ must be zero. So now combining these, we get:

$$ u \left( \rho \right) = \rho^{l+1} e^{-\rho} v \left( \rho \right)$$

In the hope that $$ v\left(\rho\right)$$ will be easier to solve than $$ u\left(\rho\right)$$. Now we want to get the radial equation in terms of $$ v$$ rather than $$ u$$. So first we'll find its derivatives:


And now subbing this into the radial equation:


Which isn't all too bad really, but is still not easy to solve. Again, lets go down the power series route, proposing a solution of the form $$ v \left( \rho \right) = \sum_{j=0}^{\infty} c_j p^j$$. The derivatives are:

$$ \frac{dv}{d\rho} = \sum_{j=0}^{\infty} j c_j \rho^{j-1} \quad \mathrm{and} \quad \frac{d^2v}{d\rho^2} = \sum_{j=0}^{\infty} j \left( j - 1 \right) c_j \rho^{j-2}$$

Subbing these in gives:


Now, by equating the coefficients of $$ \rho^j$$, we get:

$$\begin{aligned} j \left( j + 1 \right) c_{j+1} + 2 \left( l + 1 \right) \left( j + 1 \right) c_{j+1} - 2 j c_j + \left(\rho_0 - 2 \left(l+1\right) \right) c_j &= 0 \\ \left( j + 1 \right) \left[ j + 2 \left( l + 1 \right) \right] c_{j+1} - \left[ 2j - \rho_0 + 2 \left( l + 1 \right) \right] c_j &= 0\end{aligned}$$

Which gives the recurrence relation:

$$ c_{j+1} = \frac{ 2 \left( j + l + 1 \right) - \rho_0}{\left( j+1 \right) \left( j + 2l + 2 \right)} c_j$$

But at large $$ j$$ (and $$ \rho$$), $$ c_{j+1} = \frac{2j}{j \left( j+1 \right)} c_j = \frac{2}{j+1} c_j $$. Suppose this were the actual solution, then:

$$ c_j = \frac{2}{j} c_{j-1} = \frac{2}{j} \frac{2}{j-1} c_{j-2} = \cdots = \frac{2^j}{j!} c_0$$

And then:

$$ v \left( \rho \right) = c_0 \sum_{j=0}^{\infty} \frac{2^j}{j!} p^j = c_0 e^{2\rho}$$

By the power series definition of the exponential function. Hence:

$$\begin{aligned} u \left( \rho \right) &= \rho^{l+1} e^{-\rho} v \left( \rho \right) \\ &= c_0 \rho^{l+1} e^\rho\end{aligned}$$

Which goes to infinity as $$ \rho$$ (and thus $$ r$$) tends to infinity, which is not good. These are mathematical solutions to the equation, but are not normalisable so aren't physical solutions. Thus the series has to terminate somewhere, i.e. there must be some $$ j_{max}$$ such that $$ c_{j_{max} + 1} = 0$$ (and all later terms will also be zero be the recurrence relation). Thus, by going back to the recurrence relation:

$$ c_{j_{max}+1} = \frac{ 2 \left( j_{max} + l + 1 \right) - \rho_0}{\left( j_{max}+1 \right) \left( j_{max} + 2l + 2 \right)} c_{j_{max}} = 0$$

$$ 2 \left( j_{max} + l + 1 \right) - \rho_0 = 0$$

Now, lets define the principle (my textbook called this principal, but surely that's incorrect) quantum number, $$ n$$, to be $$ \left(j_{max} + l + 1\right)$$ and thus $$ \rho_0 = 2n$$. Now going way back, remember$$ k = \frac{\sqrt{-2mE}}{\hbar}$$,$$ \rho = kr$$ and$$ \rho_0 = \frac{me^2}{2 \pi \varepsilon_0 \hbar^2 k}$$. So

$$\begin{aligned} 2n &= \frac{me^2}{2 \pi \varepsilon_0 \hbar^2 k} \\ \frac{\sqrt{-2mE_n}}{\hbar} &= \frac{me^2}{4 \pi \varepsilon_0 \hbar^2 n} \\ -2mE_n &= \frac{m^2e^4}{16 \pi^2 \varepsilon_0^2 n^2 \hbar^2} \\ E_n &= - \frac{me^4}{32 \pi^2 \varepsilon_0^2 n^2 \hbar^2} \\ &= \frac{E_1}{n^2}\end{aligned}$$

These are the allowed energies of the electron, which were known before the Schrödinger equation was developed. Though it was formulated by Niels Bohr somewhat arbitrarily. Also, $$ k$$ can be nicely expressed in terms of the Bohr radius, $$ a_0 = \frac{4 \pi \varepsilon_0 \hbar^2}{me^2} = 0.529 \times 10^{-11}~\mathrm{m}$$, which was also known at the time.

$$\begin{aligned} k &= \frac{\sqrt{-2mE_n}}{\hbar} \\ &= \frac{\sqrt{\frac{m^2e^4}{16 \pi^2 \varepsilon_0^2 n^2 \hbar^2}}}{\hbar} \\ &= \frac{me^2}{4 \pi \varepsilon_0 n \hbar^2} \\ &= \frac{1}{a_0 n}\end{aligned}$$

And that's enough, more than enough really.

This would not have been possible without the help of my textbook, "An Introduction to Quantum Mechanics" 2nd Edition, by David J. Griffiths (primarily chapter 4). It's a great text book, it helped me heaps in my study (when I actually got around to using, 2 weeks before the exam), was fairly easy to follow, and really interesting.

Thursday, July 9, 2009

Idea Block

I've spent a little bit more time coding for my game recently (as I've had the time), and added a number of new features, but I've come to the point where I can't really think of anything to add. I know there are improvements, new features, etc. I could make, but I just can't think of them.

Some of the things I've done recently are: Different colours when poisoned/frozen/weak; Changed the bullet picture; added new maps; made maps use xml; reworked threading to make it much simpler; basically finished the manual; damage bonuses when using different tower types. But all of these are pretty small changes really.

I'm sure if I could get more people to play it, they'd give my ideas, but as it is now, hardly anyone plays it (I'm around 1 hit a day, if that). But if I leave it where it is now, I can't get too many hits before the site will go down (as I'm on limited bandwidth) - that's an issue I can sort out when it becomes a problem though.

I don't want to let this die though, it's one of my greatest achievements, and I've spent a lot of time writing it. And I think it's good enough for a bunch of people to get enjoyment out of, and it can still be improved. Ah well, I'll mull it over for a bit and see what happens.

Wednesday, July 8, 2009

In mathematics you don't understand things. You just get used to them.

I read this quote the other day, and thought it was awesome. It's by John von Neumann, and according to wikiquote (and therefore true) this was a,

Reply to Felix T. Smith who had said "I'm afraid I don't understand the method of characteristics." —as quoted in The Dancing Wu Li Masters: An Overview of the New Physics (1984) by Gary Zukav footnote in page 208

There are some other great quotes there, like

You should call it entropy, for two reasons. In the first place your uncertainty function has been used in statistical mechanics under that name, so it already has a name. In the second place, and more important, no one really knows what entropy really is, so in a debate you will always have the advantage.

Truth is much too complicated to allow anything but approximations.

and a relatively well known one:

You wake me up early in the morning to tell me that I'm right? Please wait until I'm wrong.

I also want to point out the quote about him, by George Pólya:

There was a seminar for advanced students in Zürich that I was teaching and von Neumann was in the class. I came to a certain theorem, and I said it is not proved and it may be difficult. Von Neumann didn't say anything but after five minutes he raised his hand. When I called on him he went to the blackboard and proceeded to write down the proof. After that I was afraid of von Neumann.

The only place I had hear of him before was because the Neumann function (actually a particular Bessel function) turned up in the solution to the Schrödinger equation for the hydrogen atom.

And just for fun, lets see if anyone can get this sequence:

0.3, 0.4, -0.1, -0.5, -0.8, -2, -4, -10, -60, -300, -2000

Hint: these are all rounded to 1 significant figure as the decimal bit is nasty (probably irrational)

Tuesday, June 16, 2009

Sailor waiter cedar whirled

I think the title says it all.

If you don't get it you might be mispronouncing cedar, it's see-dar.

I can't take the credit for this though, it was the first two lines in a crossword a few days ago (the one on the back page of the dom post).

Vegetarian Nachos

Well I cooked dinner tonight, and I made nachos, but vegetarian style (we had no mince). It turned out rather well so I thought I'd make a record of it if anyone else wants to try it out, and so I can make it again (and perhaps improve). I made this without consulting a recipe, and it wasn't really even based on any recipe I make, more just throwing stuff together.

Ingredients

1-ish tbsp olive oil
2 small onions (1 large onion would be similar)
3 cloves of garlic (they were pretty small)
1 tin of chopped tomatoes
1 tin of kidney beans
1 tin of baked beans (I typoed here and wrote ton first time)
3-ish tbsp flour
3-ish tsp paprika
1-ish tsp chilli powder
1-ish tsp salt
1-ish tsp pepper
1 capsicum

Method:

Dice the onions, garlic and capsicum. Obviously do the garlic much smaller than the other two. Fry onions and garlic in the oil in a large pan, until the onions go to the kinda see-through cooked-ish state. Add tomatoes, drain, then add kidney beans, then add baked beans. Stir to combine relatively evenly. Add flour to thicken a little, then paprika, chilli powder, salt and pepper. I just put as much of these in as I felt was about right, approximately the amount I wrote above. Be careful with the chilli powder if you don't like your food too hot. Stir to combine again. Add capsicum. Stir some more. Simmer, covered, for 10-15 minutes. Make sure to mix it and get it off the bottom every 3-5 minutes otherwise it will stick.

When I did it I only simmered for 10 minutes, and it could've done with a few more minutes, which is why I said 10-15.

Serve with nachos. Top with sour cream and grated cheese if you like.

Feeds 1+ depending on appetite (probably 4-6)

Shrinking rt.jar

I was reading somewhere that one of the reasons java applications are slow to load is that the large, 50 MB rt.jar file (94 MB extracted) must be read from disk. A jar file is basically a zip archive, so I wondered if I could make this smaller by recompressing it.

First I used advzip, from the AdvanceCOMP set of utilities that uses the 7zip compression algorithms. Copying rt.jar to my home directory, and recompressing it using -z4 I compressed it to quite a remarkable 24 MB, for a 52% size reduction. Surely this would take less time to load? Though I'm, not sure if it would take longer to decompress, and whether the bottleneck is reading from disk, or decompressing it. Though for a device with limited hard disk space, these 26 MB could make a difference.

For a second comparison, I extracted the jar file, and made a tar.lzma version, which came in at a lean 10 MB, though this did take about 2.6 s to decompress on my computer, so this is unlikely to be a viable option. The tar.gz version was still 17 MB (as was the tar.zip version), and only took 1 s to decompress.

For a third comparison, I remade the jar file using the command line zip utility, which itself produced a 25 MB file, so I'm starting to wonder why the version that comes with java is so big.

From what I understand of the zip format is that each individual file is compressed separately within the archive, which makes it good for this kind of thing in that only the classes that need to be decompressed have to, not the entire archive, which knocks out the tar.x files (and is also why they have better compression, the one file as a whole is compressed).

The thing I don't get though is why is this file so big? I tried replacing rt.jar in my java folder with the recompressed one, and everything seemed to work fine, but I did not get any noticeable performance improvement (probably in part due to the files being in the disk cache), but I didn't want to break anything so put the original ones back.

The last thing I'm wondering is that presumably these jar files are made by a java program, using the java libraries. Does that mean the java libraries are really bad in making jar (zip) files? And if so, surely the code can be replaced with some from say the 7-zip project, at least in OpenJDK, both being FOSS projects. Maybe it already has and it'll all be seen when java 7 comes out. Who knows?

Monday, June 15, 2009

Study goodness

I just had one of my most fruitful study sessions ever today, studying for quantum mechanics. Got some tough problems done, and understood some things a lot better than I had done previously. Now for anyone who's interested, and because I want to play around with LaTeX in this blog, I'm going to show how to formulate the time independent Schrödinger equation.

We'll start with the time dependant version:

i \hbar \frac{\partial \Psi}{\partial t} = - \frac{\hbar^2}{2m} \frac{\partial^2 \Psi}{\partial x^2} + V \Psi

Where \Psi = \Psi \left( x,t \right) i.e. a function of x and t, and likewise for V.

Now we shall assume \Psi \left( x,t \right) = \psi \left( x \right) \phi \left( t \right) i.e. it is separable.

Then the equation becomes:

i \hbar \psi \frac{\partial \phi}{\partial t} = - \frac{\hbar^2}{2m} \phi \frac{\partial^2 \psi}{\partial x^2} + V \psi \phi

and dividing through by \psi \phi gives:

i \hbar \frac{1}{\phi} \frac{\partial \phi}{\partial t} = - \frac{\hbar^2}{2m} \frac{1}{\psi} \frac{\partial^2 \psi}{\partial x^2} + V

If V is only a function of x, then the left hand side is dependant on t alone, and the right hand side is only dependant on x, therefore they must be equal to some constant. Lets call this E.

Now, it is easy to solve for \phi:

\begin{align*}
i \hbar \frac{1}{\phi} \frac{\partial \phi}{\partial t} &= E \\
\int \frac{1}{\phi} \frac{\partial \phi} dt &= \int \frac{E}{i \hbar} dt \\
\ln \left| \phi \right| &= - \frac{i E t}{\hbar} \\
\phi &= e^{- \frac{i E t}{\hbar}}
\end{align*}

Note that the left side is always positive, so the absolute value works out alright.

The other part of the earlier equation becomes the time independent Schrödinger equation:

- \frac{\hbar^2}{2m} \frac{\partial^2 \psi}{\partial x^2} + V \psi = E \psi

Which can only be solved if the potential, V, is defined.

Now I hope that is accurate, but is not unlikely that I made a mistake somewhere.

Sunday, June 14, 2009

Double contractions

I don't think these are technically correct, but I find them awesome, and oh so interesting. If I were one of the ones making the rules for English, I'd've included them. Ah well, they can still be introduced through incessant usage.

The one I find most interesting is it's'nt (it is not), as it can be expanded to have an ordinary contraction in two ways, it's not and it isn't. Has a strange, but nice sound, I reckon. (Learning Japanese causes me to append the verb on the end often, rather than using it at the beginning as is the more natural way in English - ah well)

There are lots of others, at times I even find myself using them unintentionally, like couple of hours ago, I used they'd've (they would have). So why not try and use a double contraction this week. Go on, I dare you.

But triple contractions, they're just ridiculous.

Laughter is good

And I just got a whole lot of it watching this video. Warning: It is 24 minutes and contains a whole lot of swearing. It's fully worth it though.

But as I was saying, laughter is good, it can make your day, and lack of it can break it. That is all.

I just wanted an excuse to post the above video, really.

Saturday, June 13, 2009

Wikimedia Pictures of the Year 2008

They're out. I discovered that wikimedia did this a while ago, and had been waiting for ages for this to become official, it's what, 5 months and a bit after the end of 2008 now, but I understand that these kind of things take time. This year is impressive as the previous two, though I can't say I'm all that big a fan of the picture who won, preferring 3, 4 and 18 (the 2nd 18) in particular.

I recommend checking this out, all the pictures are nice, some of the animated gifs are very impressive, like the cicada one, and who knows? You might find a new desktop wallpaper, I did.

Nice going Redmond

As some of you may know, Aaron Redmond hit a sizzling 63 off 30 balls in New Zealand's victory over Ireland in the 20-20 world cup. This is a tremendous score, especially for someone who was only playing due to injuries to other team members. At the time of writing this blog, it was the 8th equal highest score of the tournament so far, and there was only one score higher than his at a greater strike rate. It's also the highest score by a New Zealander (again at the time of writing).

This brings a bit of a problem on the NZ selectors, if Ryder (and possibly other injured players I'm overlooking) become fit and able to play again, do they drop the in form player? and if not, who do they drop? Though this is a better situation than they have faced recently, having to choose which out of form players to select.

The other thing that a little unusual about this success story is that the only games that Redmond had played for NZ prior to this match were tests, where he had been moderately successful. I only hope he can keep up this form, and keep demanding a place in the NZ side.

Thursday, June 11, 2009

Testing, testing, testing, testing,

When I released a new version of my game (shameless plug) a couple of days ago, I fell into the trap of insufficient testing. I had made some quite big changes and never tried actually playing one of the new levels. After I had uploaded it, and changed all the necessary pages with details of it - my entire release process, I tried playing it. Within 10 s of starting a new level, the game freezes. Shoddy testing.

It turned out that I was using way too much memory (to get good performance with that version you'd need to allocate the JVM something like half a gigabyte of RAM). This was due to some oversights in earlier code causing failures with the new maps (and caching way too many images). It took me a couple of days to fix - in which the game was effectively broken (though the older levels would still have worked fine). I just uploaded a newer version which I hope fixes the problem, and seems to, but I didn't test that release enough either.

I don't think I'll ever get to the point of thoroughly testing each release of this myself, as it's way too much effort, but this experience highlights the need to do at least some testing of how it would actually be used before releasing a new version.

An amusing site I found

While surfing the interwebs (I'm not very good so sometimes fall in), I found this site. I found it amusing so thought I'd share. It reminded of another site I came across not so long ago.

It also contains one of my pet peeves: a gif image. Nowadays, gif images should only be used when an animated image is required as png images will almost always give a smaller image, at no loss of quality. For instance, I downloaded the image, and ran it through optipng (to convert it to a png and do some png compression stuff) and achieved a 51.76% file size decrease. Then I managed to shrink it a further 6% using advpng -z4. A file less that half the original size of exactly the same quality is not to be sniffed at.

This page also contained an Easter Egg, which wasted around half an hour of my time (not finding it, that was trivial, but the page itself), though it to was amusing. There I found yet another amusing link of a similar variety.

Enjoy.

Sunday, May 24, 2009

Life is a game

Just a thought that I had in the shower this morning and stuck a little bit. I'm not saying I'm totally behind this, but just thought it was interesting.

Firstly, the point of a game is to have fun. Some people say it is to win, but simply put, they're wrong. Winning is just an added bonus. Thus, if life is a game, the point to life is to have the most fun possible. This leads to a number of things, like keeping yourself in a good condition to be able to have fun in the future. Having more fun now, but in such a way as to reduce the amount of fun you can have in the future, may lead to having less fun overall.

Taking drinking as an example. Lots of people say it is fun to drink, to get wasted, to get off your face. However, this can adversely affect your future potential for having fun - you could get alcohol poisoning, injure yourself, drink and drive and have an accident, all manner of things. Though these aren't the norm, the norm is you're fine. Say 1 time out of 100 you get wasted something bad happens, ranging from the fairly bad to death. If you only get wasted once, your chances are good, but say you do it every weekend for two years, approximately 100 times, then you've got a 63% chance that at least once something bad will happen. 3 years, 78%, 4 years, 87% and 10 years 99%. Now, these bad things can clearly reduce your potential to have fun in the future, so moderating the amount you drink looks like a good idea, statistically.

The same argument can be made for a plethora of other things that people see as 'fun' such as taking drugs, kayaking down a river, having sex, tramping, etcetera. However, you can't just eliminate everything that has any potential chance of something bad happening, as then the amount of fun you'll have overall would also be reduced. So if you see life as a game, you've got to find the balance for what is the right level of risk to take in order to be likely to get the most fun overall. Then there is the luck factor, there are some people that do ridiculously dangerous things all their lives and nothing bad seems to come to them, while there are others who get messed up after the first attempt.

Just something to think about.

Saturday, May 23, 2009

Fragile Base Class Problem - Not Quite

I have never encountered the fragile base class problem when programming, but I encountered something remarkably close when I was writing code for our comp sci group project today.

I was extending the DefaultMutableTreeNode class. It has two remove methods, remove(int childIndex) and remove(MutableTreeNode node) for removing children from this node. I was overriding these two methods as I was keeping a separate map of the nodes, my remove(int childIndex) method found what node was at childIndex, and them called remove(thatNode).

Now, my remove(MutableTreeNode node) method would remove the node from my map, and then call the superclass' remove method. The superclass' remove method must have been (confirmed by looking at the java souce code) calling remove(int childIndex), which I had overriden, so my version got called, which called my other remove method, which called the superclasses remove method - loop until the stack overflowed. Was pretty easy to see that this was happening from the stack trace.

Now, the fragile base class problem is when changed a base class causes a derived class to break, where this is slightly different in that the implementation of the base class caused the derived class to break. Now, if the DefaultMutableTreeNode class were changed so that the remove(int childIndex) called the remove(MutableTreeNode node), then I would suffer the fragile base class problem.

Oh the joys of programming.

Crazy Double Chat

As you may, or may not know, I use Emesene in the place of MSN messenger or Windows Live or whatever it's called nowadays as I use Linux, and the MS variant doesn't run on Linux (it may do under WINE, but I wouldn't use it anyway as Emesene meets my needs). While it does strange things from time to time - like not display a line I just typed in the window at my end, but will at their end, something that happened today really took the cake.

I was chatting with a friend of mine today (about out comp sci group project). Then a new conversation was started with her and another member of our group (3 way conversation). I left the previous window open, as you do. Some of us have dinner, and for various other reasons, no chat takes place for a few hours, in which I leave these windows open.

Now, it comes to the point where I want to ask a question, to the second person. So I go to the 3 way conversation and ask if she's still there. As soon as I do this, that conversation changes to a 2 way conversation as if she had gone offline, even though she was still online. Then the first person replies "...? wrong person?" Which I thought was odd as surely she would've realised it was the group conversation.

Then I realise, that the "...? wrong person?" also appeared in the first, 2 way chat, between her and myself. And every line she wrote from then appeared in both conversations, and she was receiving the messages I typed into the boxes on both chats.

The net effect was I had two chat windows talking to her one, her lines went to both of my windows, but my lines in either window went to her one window. Pretty cool huh? Though useless and crazy nonetheless.

Wednesday, May 20, 2009

Stab proof sheep, and the opposite of strange

Today was a good day for the random anecdotes, I'll recount a few of the more amusing ones now.

According to one of my physics lecturers, citing wikipedia [confirmed], using a small fraction of niobium in a steel alloy makes it much stronger (I think he said 10x).

According to another guy in the same class, there are new stab/bullet/everything proof vests being developed using merino wool and other things. Apparently they can only sew this very slowly to avoid wrecking the needles. This has important connotations. Firstly, NZ, with it's high number of sheep has the potential to become an economic powerhouse because of this. The second, and potentially more deadly, is that how long will it be before we get stab proof sheep? You thought those sheep were so cute, well, I for one welcome our new woolly overlords.

Next, have you heard of the new search engine-style thing, Wolfram|Alpha? Well, at our youth group planning meeting tonight, it came up in conversation, and apparently it can tell you how many fish are in the ocean. I just tried this, and it states \inline 2 \times 10^9 metric tons. It also lists all the approximations it made along the way. This wasn't quite what I was expecting, as it didn't tell you the actual number of fish, and more importantly, it misspelt tonne. I then asked for the average weight of a fish, which failed so I see why it can't answer.

The other thing I tried in it previously, was to ask how many basketballs would fit in the ocean, which failed. Trying to find the fault, I asked what the volume of a basketball was, which failed, though it did manage to answer the much more difficult, "What is the volume of the ocean?" Ah well, give it time and it's sure to be able to answer a whole lot more trivial questions.

Lastly, I got this somewhat cryptic text message today, "Oposite spin to strange?" Your job is to answer it (I texted back the answer as soon as I read the message, was part of a pub quiz apparently). Hint: Subatomic particles.

I hope you found those as amusing as I did.

Sunday, May 17, 2009

Looking at things now, compared with then

Do you ever look at something a while after you did it, and realised that it wasn't actually what you perceived it to be then? I don't know if this happens to you, but it happens to me all the time.

The example that made me think of this, was earlier today I was writing a lab report for the NMR lab I did just over a week ago. In one of the experiments you had to choose the right capacitor value so the amplification would be as centred on the frequency of resonance as possible. You can forget all that if you want to as you don't need it for what follows. On the day, we chose 11 nF as that looked the best (I specifically remember thinking this). But when I was writing the report, 11.1 nF was clearly better. In my report I had to write, "On the day, the 11 nF run looked the best so that was what was used for the remainder of the experiments, but looking at it now, the 11.1 nF one looks marginally better."

It happens to me all the time. I'll have a maths problem in my assignment that I'll puzzle over for ages and not get it. Then look at it later and it'll all be clear. Or similarly, I'll give a long, complicated proof or example, then look at it later and think of a much simpler version. There are all sorts of things like this. (Though on second thoughts, these two can be explained by me thinking over in the time in between.)

For good measure, I'll throw in those times when something seems like a good idea when you do it, but you look back and think, "Why did I do that? That was stupid."

I've rambled enough now, I think.

Saturday, May 16, 2009

The joys of the train (in NZ at least)

I remember a couple of weeks ago, I was catching the train home from university, and when I got to the station, the LCD stated that the train was running up to 5 minutes late. I didn't think that was too bad, it's pretty normal for the trains to be running a few minutes late.

After I had been waiting at the platform a few minutes, there was an announcement apologising for these still "up to" 5 minute delays. At that point it was already 3 minutes after the train was meant to have departed. As I listened to the announcement, I remember saying, "up to" in a sarcastic tone and a guy standing beside me agreed that the use of those words was probably not wholly accurate.

A few minutes later, now almost ten minutes after the train was meant to have departed, another announcement comes, now the train is "about" 10 minutes late. Lo and behold, only 2-3 minutes after this announcement the train arrives!

What I object to about this whole thing is not the fact that the train was running late, that happens, and we have a rather run down rail service, thanks to that almighty cure-all known as privatisation, but that's another whole story, but instead the way they stated the lateness. Surely they would have known that the train was likely to be more than 5 minutes late, so why use the specific term, "up to"? Surely it would have been more accurate if they had stated "about" at first. Ah well, the state of people's England is ever improving.

My amazing coding discovery

I just discovered that in C and Java (and presumably other languages as well), the following is perfectly valid syntax:
var1 = var2 = var3 = something;
To, as is reasonably obvious, the value of the three variables to something. Which (to me) is a whole lot nicer than doing the same over three lines, as I've always been a big fan of not using extra lines unnecessarily. This goes up there with my other favourite space saving technique, the ternary operator which takes the form:
var = boolean ? someValue : someOtherValue;
Where if the boolean evaluates to being true, var will be set to someValue and if it is false, someOtherValue. You've done on one line what would've taken four with if/else statements! I've even been tempted to use nested ternary operators sometimes, but this quickly becomes illegible, which ain't the best.

Anyways, back to the = = = thing, I actually first found that out in a physics lab a couple of weeks back, when I had to set three registers to the same value on the microcontroller to set up three timers I think it was. Though I was having issues at that point so I think I just changed it back to make sure it'd work. I then had the perfect situation to use it on our group project, and it worked fine, so I'm never going to look back. I haven't learned such a trivial yet handy language feature like that in a while so it felt like when I had just learnt about var++ and var *= something and the like.

And, three quarters of the way through writing my first blog post I change from using the nice (but laggy - being google probably lots of javascript) rich text editor I've gone to using the plain html - go figure.