# Map Take 2: The Slicening

posted on 2012-11-30 22:05:50

It's been a while since I wrote about my scientific computing library for lisp: map.  Map is a great exercise for me -- in learning Lisp and learning algorithms and optimization.  Since I'm between jobs and not yet in grad school, the time has been ripe to work on the library with some toy cases and try to make it as usable as possible by the time I get back in a position where I could use it for real work.

Because of my copious free time, a lot has been changing lately, including the addition of matrix slices, which were important, and such important features as matrix inversion.  I'm also looking at adding parallelization at some point, as well as a matrix-defining macro in the style of the #v() one for vectors.

In any event, here's what's new:

# Slices

I promised to write again when I had finished with matrix slices in map.  I'm sure they're not in their final state, but I have implemented them in a way that works. Now you can do things like:
(setf (mref m 1 #r(1 2) t) #2a((2.0d0 1.0d0 3.4d0) (3.1d0 3.2d2 4.2d1)))

Which already has a number of things going on in it.  This is setting a sub-matrix of m, a rank-3 matrix to a rank-2 matrix specified in the end of  the setf call.  Since we selected a single value for the first index of m, mref will not count that dimension as extant for the purposes of comparing with the shape of the matrix we're assigning.  This is really useful, because now things like multiplying matrices can be done like this:
(defmethod .* ((A simple-array) (B simple-array))  (with-result (result (list (array-dimension A 0) (array-dimension B 1)))    (do-matrix (result (i j))      (setf (aref result i j) (dot (mref a i t) (mref b t j))))))

There are three different ways you can specify subscripts to mref:

1. Integers
This will work like aref, and the dimension won't be included in the final output

2. Ranges
This will select all entries in the matrix that have indices inside the specified range in this dimension, for example, (mref #(1 2 3) #r(0 1)) ==> #(1 2)

3. t
This selects all elements in this dimension.  It's great for slicing rows/columns out of matrices a la (mref m t 0), which will take the first column out of m.

# Matrix iteration

Since most of the functions in the library were operating on matrices and returning new ones, I thought some macros were in order.  I think it's the reflex of any lisper to write a macro when they see the same code in more than one place.

Of that urge were born (with-result) and (do-matrix)(with-result) is simply a convenient way of defining a new matrix at the start of a function and automatically returning it.  (do-matrix), though, I rather like because it allows looping over matrices in a rather intuitive way.

(defun mandelbrot (matrix)  (with-result (result (list 1001 1001) 'integer)    (do-matrix (matrix (r i))      (setf (aref result r i)	    (loop	       with c = (aref matrix r i)	       with z = c	       for i from 0 upto 80	       if (> (abs z) 2)	       return (1- i)	       else	       do (setf z (+ (expt z 2) c))	       finally (return 80))))))

Here you can see (do-matrix) at work, testing whether each element of an array of complex numbers is in the Mandelbrot set.  It's definition is
(defmacro do-matrix (matrix &optional subscripts) ...)

which means you can then just write element-wise operations inside the loop with all of the indices figured out for you.

I'll end with the figure I made of the Mandelbrot set today on the [-2, 2] range in the complex plane. Along with the (mandelbrot) function above, you need the matrix to call it on,

(mute  (setq cm	(let ((center 500))	  (with-result (result (list 1001 1001) '(complex double-float))	    (do-matrix (matrix (r i))	      (setf (aref matrix r i)		    (complex (* (- r center) (/ 2.0d0 500))			     (* (- i center) (/ 2.0d0 500)))))))))

and then you can run
(mute (setq r (mandelbrot cm)))(image r)

.

# Minecraft Mods on Mac Leopard

posted on 2012-11-26 09:40:14

For the last few days, I've been trying out the Better than Wolves mod for Minecraft.  The mod makes a lot of things harder, and most importantly, adds mechanical power to the game alongside the magical redstone power it already had.  With tools like MCPatcher, this sort of thing is pretty easy, but once again minecraft's Java bit us in the butt when it turned out Sarah's computer, which runs the Mac OS version 10.5 is no longer supported and doesn't have a version of Java later than 6.

Apparently, it comes configured to use version 5, though.  For some reason.

Anyway, we spent the last day trying different ways of patching the game so she could use it, including doing it on a GNU/Linux box and emailing the modified jar file to her.  The most coherent thing I could recognize out of the Java backtrace was something about class versions.  I know Java is stored in class files, and so I reasoned it was something about some version of Java not playing well.

Long story short, if you find yourself in the same position, follow the instructions of the fellow here, which I will reproduce below in case the forum they are posted to has ceased to exist.

1. Right click the Minecraft App and select "Show Package Contents", then select info.plist

2. In info.plist look for the lines of "JVMVersion 1.5+" change the 5 to a 6 then save and close the file

3. Open a finder window and go to /System/Library/Frameworks/JavaVM.framework /Resources/Mac OS

4. Copy the file named JavaApplicationStub

1. Go back to the Contents folder in the Minecraft app

2. Open the folder MacOS

3. Paste JavaApplicationStub into the folder

5. Next find and open “Java Preferences” in finder

6. In the “General” tab there should be a list of the Java versions you have. If “Java SE 6″ isn’t on the top of the list then drag it to the top.

7. Patch Minecraft at will

That is all.

# Reflections on a year of Job-Hunting

posted on 2012-11-15 21:28:49

The past year has been one of unending frustration and despair.  I've had jobs, sometimes even jobs in Physics, which is my favorite kind of job, but even those have paid little, been short-term only, and sometimes been in very unwelcoming environments. I feel a lot of anger and frustration, because I feel like a lot of people misled me.  I don't think they did it on purpose, and I think a lot of it is disconnection with some parts of life both on my part and the parts of others.  I think my professors didn't know what sort of world they were sending me into, and I think they generally assumed either that my classmates and I wouldn't be continuing with Physics, or that we would be going right to graduate school.

I do think many of my classmates jumped off the Physics ship as soon as they got done with college.  But I know I've felt rather lost in the last year, which feels like it has been far longer, with some significant help from my research adviser, Kiko Galvez, in terms of names to talk to and introductions, but by and large, the year feels like a random walk experiment.

Let's think about the degrees of freedom for this random walk:

## Where is the available job

Moving is tough.  Trust me, I've done it at least annually for the last five years.  Once you start owning more than a bag of clothes and a computer, it becomes a serious undertaking that eats up days and requires large amounts of truck/storage space to execute.  Even then, it requires lots of planning and labor.

Understandably then, I don't really want to have to do it, and companies don't really want to help me do it because it costs them money, and, well, there's this guy who already lives here and can do the job, so let's hire them.

## What is the job called, and do I know that title means "you can do this"?

This is my favorite. I have no idea what I should be typing into job search engines.  Should I be 'technical support staff,' 'assistant researcher,' 'open-rank lecturer,' or maybe a 'wind resource analyst.'

## Do I use the right words to describe myself

You used a bunch of words in your job posting that I don't understand.  I'm not a black belt and I don't know what bearing that has on electrical engineering.  I think I'm far more likely than six-sigma.

I've looked these things up now, but they sound too stupid for me to ever consider signing up for a course in them.  Plus, I only need a job for a year or so, until I can get back into grad school.

## You can't do Physics with a degree in Physics

I dare you to try. Apparently, what professors meant when they said "you can do anything with a degree in Physics," is "I have no fucking clue what you can do with a career in Physics.  In the realm of research jobs in Physics, I need to be in graduate school, and I wish somebody had told me two years ago so I didn't have to look for a job and a grad school at the same time.

# Literary Programming

posted on 2012-11-15 21:27:40

I've been doing a terrible job of writing recently -- something I'm happy to put down to the general depressing-nature of the life of the unemployed -- and I'm definitely overdue on some writing. I've now moved out of Washington Heights in New York, and into Evanston, just north of Chicago. So far I'm liking it here. It's similar enough to New York City in a lot of ways, but with much more space, and less of the claustrophobia that is endemic in NYC.

Now that I've reached a moment of coherence, I'd like to just throw down a link I thought was particularly interesting.

If Hemingway Wrote Javascript

This was notable for a number of reasons.  First, it was an entirely new genre of thing to me.  I had never seen anyone write about writing styles in programming before.  I don't mean style guides or best practices, but just what you express by the way you choose to do things.  I think the author did something really cool here, ranging from his interpretation of Hemingway, who wrote a very clear, straightforward implementation, to the different failings of programming style he showed in some others.

Even though the example of Breton is obviously written to be a bit silly, framing it as an author made me think about the example in a different light.  I'm a fan of work of the Dadaists, who did strange things because things are strange and the things we are used to only seem normal because we are used to them.  The idea of renaming the push() function of arrays to something else -- maybe even something more expressive -- strikes me as potentially helpful.  In languages where the language itself can be dynamic, as in Lisp or Javascript (and I'm sure others, I just only know what I know), maybe it makes more sense sometimes, to rename things to reflect what they're being used for.  If Lisp has taught me anything, it's that programming is just code manipulating data, and trying to render that clearly is the greatest struggle.

Finally, I can't leave this without mentioning the work of the imagined Dickens, who is someone I found very frustrating to read.  I consider A Tale of Two Cities to be one of the worst books I've read, and it was only through sheer will that I finished it at all.  Apparently, as quoted in the article:
If we might hazard a definition of his literary character, we should, accordingly, call him the greatest of superficial novelists. We are aware that this definition confines him to an inferior rank in the department of letters which he adorns; but we accept this consequence of our proposition. It were, in our opinion, an offence against humanity to place Mr Dickens among the greatest novelists. For, to repeat what we have already intimated, he has created nothing but figure. He has added nothing to our understanding of human character.

What I mean with all of this, and think of A Tale of Two Cities and the imagined Dickens implementation of the Fibonacci function is that they each manage to be what they set out to be -- a novel and a function -- but just in the meanest sense of the words.  A Tale of Two Cities has a story -- but only in that it relates a series of related events -- and the function returns the right function and in both cases, I feel like I'm squinting at them with, "That's not quite right," on the tip of my tongue.