repak shawahb
armed and hammered

^

   

rsw@jfet.org


blogroll

       
Mon, 15 Jun 2009

wrap this

rlwrap is awesome. It takes any commandline tool and makes it behave like it uses GNU readline.


[ permalink | 0 comments (add one you lazy bastard!) ]

Sun, 14 Jun 2009

yay!(cd)

or, Yet Another Y-Combinator Derivation

In the comp.lang.ml FAQ one of the questions asks about the Y-combinator; the answer is provided without derivation or explanation of the subtle datatype backflip you need to use. So we'll derive it together here.

We've all seen the standard Y-combinator derivation in Scheme, right? Y is a fixed-point combinator which represents, in effect, the distilled essence of recursion. To sketch Gabriel's argument (in Scheme first), we start with an example recursive function—factorial, of course:

(define fact (lambda (n) (if (= n 0)
                             1
                             (* n (fact (- n 1))))))

> (fact 5)
120
>

Now, what we want to do is define fact without using fact—so what if we change it so that we can pass the function in that we'll call recursively?

(define f (lambda (fz n) (if (= n 0)
                             1
			     (* n (fz fz (- n 1))))))

But what function do we pass in as fz? f itself, of course—it'll happily keep passing itself all the way down to the base case, and what we get out is factorial.

> (f f 5)
120
>

Now, for reasons which will become clear in a second here, we will curry this function, i.e., turn one function of two arguments into two nested functions taking one argument each:

(define ff (lambda (fz) (lambda (n) (if (= n 0)
                                        1
					(* n ((fz fz) (- n 1)))))))
> ((ff ff) 5)
120
>

See? Basically the same thing, but now ff takes one argument—another function—and returns a function that takes a number and returns its factorial. But we're not done yet: we started with (fact n) and now we have ((ff ff) 5). Well, let's start by fixing the recursive call, recognizing that we can hide the (fz fz) inside lambda:

(define ff (lambda (fz) (lambda (n) (if (= n 0)
                                        1
					(* n ((lambda (n) ((fz fz) n)) (- n 1)))))))

Well, that lambda in there is ugly, but we can always just pull it out and then pass it in via a variable:

(define ff (lambda (fz)
                   ((lambda (z)
		            (lambda (n) (if (= n 0)
			                    1
					    (* n (z (- n 1))))))
		    (lambda (n) ((fz fz) n)))))
> ((ff ff) 5)
120
>

It doesn't look like we're getting any better in terms of recovering the original (fact 5) syntax, but I assure you we're getting closer. Recognize that we could recover the original behavior by just defining a new function fff like this:

(define fff (lambda (n) ((ff ff) n)))

Yup, we've seen this trick before. But let's expand out the (ff ff) so we can do just one definition:

(define fff ((lambda (fz)
                     ((lambda (z)
		              (lambda (n) (if (= n 0)
			                      1
					      (* n (z (- n 1))))))
		      (lambda (n) ((fz fz) n))))
             (lambda (fz)
	             ((lambda (z)
		              (lambda (n) (if (= n 0)
			                      1
					      (* n (z (- n 1))))))
		      (lambda (n) ((fz fz) n))))))
> (fff 5)
120
>

And we've done it. Nothing but arithmetic operations and passed-in function names for defining a recursive operation. But we can generalize this by realizing that we can separate out the "guts" of factorial relatively easily:

(define Fguts (lambda (z)
                      (lambda (n) (if (= n 0)
		                      1
				      (* n (z (- n 1)))))))

This is a function that requires us to pass in the recursive continuation, so it is not itself recursive, and even better, now that we've defined it we can pull Fguts out of fff and make it somewhat prettier:

(define f3 ((lambda (fz) (Fguts (lambda (n) ((fz fz) n))))
            (lambda (fz) (Fguts (lambda (n) ((fz fz) n))))))

This is identical to fff, but we've folded the mess into Fguts. Note that we are still using (lambda (n) ((fz fz) n)) just as before—because this was really the first glimmer of the prize. Consider adding one more layer of lambda where we completely generalize by passing in Fguts or any other "guts"-style function:

(define Y (lambda (X)
                  ((lambda (fz) (X (lambda (n) ((fz fz) n))))
		   (lambda (fz) (X (lambda (n) ((fz fz) n)))))))

And we've arrived at the applicative-order Y-combinator. Taa daaaaaaa!

> ((Y Fguts) 5)
120
>

So could we do the same thing in Standard ML? Well... kind of. The type system gets kind of bitchy if we try to follow exactly the same derivation:

- fun f fz 0 = 1
=   | f fz n = (n * (fz fz (n-1)));
stdIn:3.20-3.31 Error: operator is not a function [circularity]
  operator: 'Z
  in expression:
    fz fz

Many ML programmers are unaware that there is a trick to deriving the Y-combinator in the same wy as above; we simply have to define a recursive datatype so that the type checking unification function doesn't complain about circular substitutions:

datatype 'a t = T of 'a t -> 'a

Now we can start at the top (almost; we'll take advantage of SML's automatic currying for now):

fun ff (T fz) 0 = 1
  | ff (T fz) n = (n * (fz (T fz) (n-1)))

- ff (T ff) 5;
val it = 120 : int

The above step is conceptually the most important and difficult in terms of getting Hindley-Milner on our side. ff has type (int -> int) t -> int -> int, meaning that we will need to keep the same fz (T fz) structure throughout the rest of this derivation. Without it, the type inference system will shun our circular definitions.

Continuing the same argument as before, we wrap the ugly fz (T fz) inside a lambda, then pull it out as an argument (with a little acrobatics because we can't take advantage of automatic currying for this step):

fun ff (T fz) 0 = 1
  | ff (T fz) n = (n * ((fn n => (fz (T fz) n)) (n-1)))

(* now pulling the new "inner function" out *)

fun ff (T fz) = ( ( fn z => ( fn 0 => 1
                               | n => (n * (z (n-1)))
		            ) )
                  ( fn n => (fz (T fz) n) ) )

Now we're ready for fff, and ditching the fun syntactic sugar completely.

(* fun fff n = (ff (T ff) n) *)

val fff = ((fn (T fz) => ((fn z => (fn 0 => 1
                                     | n => (n * (z (n-1)))))
                          (fn n => (fz (T fz) n))))
           (T 
	   (fn (T fz) => ((fn z => (fn 0 => 1
                                     | n => (n * (z (n-1)))))
                          (fn n => (fz (T fz) n))))))

We're close now! Time for Fguts (returning for the sake of brevity to automatic currying) and then f3:

fun Fguts z 0 = 1
  | Fguts z n = (n * (z (n - 1)))

val f3 = ((fn (T fz) => (Fguts (fn n => (fz (T fz) n))))
          (T
	  (fn (T fz) => (Fguts (fn n => (fz (T fz) n))))))

So close we can taste it. Abstracting Fguts gives us the Y combinator once more:

val Y = fn X => ((fn (T fz) => (X (fn n => (fz (T fz) n))))
                 (T
		 (fn (T fz) => (X (fn n => (fz (T fz) n))))))

Thus sayeth the interpreter:

val Y = fn : (('a -> 'b) -> 'a -> 'b) -> 'a -> 'b
- (Y Fguts);
val it = fn : int -> int
- (Y Fguts) 5;
val it = 120 : int

By the way, there is a ridiculously simple way to define precisely the same Y-combinator in SML:

fun Y f n = f (Y f) n

(* or, using the built in compose operator "o" *)
fun Y f n = (f o Y) f n

Of course, both of these "cheat" because they're explicitly recursive.


[ permalink | 0 comments (add one you lazy bastard!) ]

Mon, 08 Jun 2009

formalism paradox

In perusing the veritable cornucopia of languages mentioned in my previous post (and others), I've noticed a curious pattern: languages with formal standards are, strangely enough, the ones most likely to have several competing, somewhat incompatible implementations. Languages like Standard ML, Common Lisp, Haskell, Scheme, and C are all standards-based, and yet their respective compiler/interpreter implementations have various incompatibilities.

Conversely, Perl and OCaml, whose featuresets are basically defined by their implementations, have essentially one version each (OCaml has VM versus native compilation, but with common maintainers).

Now, having multiple competing implementations certainly has its upsides, and I'm in no way arguing that it's bad to have a formal standard. It is really weird to consider, though: having a standard naturally encourages multiple implementations, which are almost certainly going to have at least some inconsistencies. By eschewing formal standards and adopting the perl "descriptive" (versus authoritative) documentation model, you virtually guarantee interoperability.


[ permalink | 0 comments (add one you lazy bastard!) ]

postpartum bliss

The chip taped out last Thursday; Friday I did some final cleanup stuff, and now I'm off until Friday. So now I'm just hanging out doing nothing.

Not really nothing. I might go out and buy inFAMOUS at some point—the demo is freaking badass and you should stop reading this and play it immediately—but right now I'm busy.

With what, you'll ask? Learning me some new programming languages. Yeah, plural—Standard ML right now, but I also plan to learn some subset of [Haskell, Erlang, OCaml]. In fact, Joe Armstrong's Programming Erlang is sitting right next to me on the couch because the nice mail lady just dropped it off; first impression is that it's a very decent deal at $25. The forthcoming Erlang Programming book from O'Reilly may also be good, but Armstrong seems to be universally loved, so I'm not going to argue.

The SML book I'm reading right now is one available online, Programming in Standard ML by Robert Harper. It's well written and gets you going. I burned through 10 chapters of it in a couple hours yesterday, and I've been playing around with what I've learned so far to help the syntax set in. So far, my impressions are that type inference is an astoundingly cool idea, and while SML/NJ is friendly inasmuch as it has a REPL, MLton produces code that runs substantially faster. Identical implementations of Rabin-Miller (modulo the differences in library calls) yielded a 3500x (yes, ~3.55 orders of magnitude) difference in speed. I'm pretty sure this implies that my implementation is crap and MLton is optimizing away my painful scribblings. Also with regard to SML/NJ versus MLton, the build sequence for the former is more annoying than for the latter—but that's what makefiles are for, so it's hardly worth mentioning (though the documentation on the build process is admittedly somewhat annoying).

Anyway, also on the menu for SML are UNIX System Programming with Standard ML (free online) and ML for the Working Programmer (can be had for like $12 used on Amazon). The MLton.org wiki's Standard ML page and the SML/NJ literature page also list some more resources, and the SML sourceforge project has good SML basis library documentation.

For OCaml, the official user's manual is free, very complete, and is well regarded. There is also Introduction to Objective Caml by Jason Hickey, which despite being distributed from the Caltech website comes with ominous redistribution warnings. Apparently Practical OCaml by Joshua B. Smith is fucking terrible, so I'm not even bothering to link it. On the other hand, OCaml for Scientists seems well regarded. You can find it in DjVu format from a few pirate websites, but please buy the book if it's any good—or steal it brazenly if it's bad, I guess. Wikipedia lists a few online tutorials in the "External links" section of the OCaml article.

Among Haskell books, the best received seems to be the newish one by O'Reilly, Real World Haskell. You can read the whole thing online and perhaps even get lost in the paragraph-by-paragraph comments. I don't know enough about other resources to make specific recommendations, but the Haskell Wiki's Learning Haskell page has a bunch.

While I'm nerding on programming languages, I gave F# a spin under mono and, impressively, it works. It's pretty trippy to see this pop up in an xterm:

[kwantam@muon ~/Desktop/FSharp-1.9.6.16/bin]$ mono ./fsi.exe 

Microsoft F# Interactive, (c) Microsoft Corporation, All Rights Reserved
F# Version 1.9.6.16, compiling for .NET Framework Version v2.0.50727

Please send bug reports to fsbugs@microsoft.com
For help type #help;;

> _

Brings me back to my old QBasic days. Speaking of which, apparently the FreeBasic project is pretty badass. I say this just in case you're missing nibbles or gorillas.


[ permalink | 0 comments (add one you lazy bastard!) ]

Sat, 30 May 2009

mouserx

My old work mouse, a borrowed-ish MS Intellimouse Explorer 3.0A, had this odd habit of causing X to crash every once in a while. I don't know how this is possible, I only know that it had to do with the scroll wheel and it was very hard to reproduce. (OK, I can't say 100% for sure that it was actually the mouse, but the frequency of crashing with the same usage model dropped to zero abruptly after switching, which is good enough for me until I find a counterexample.) It may be that the thing is dying and somehow exposing a flaw in the xorg evdev driver.

All of that is beside the point. I went out and bought a new mouse, which was a frustratingly difficult task: apparently everyone likes their mouse wheel to feel like rotting fruit, whereas I want positive, LOUD clicks like the nearly unused Logitech bottom-of-the-line optical mouse connected to positron. Aside: I really ought to do something other than VGA mode on a text console considering I spent the $80 on an 8800GT when I rebuilt positron last year, right? Oh well.

So, because I wasn't particularly happy with any of the scroll wheels, but because I did still want a new mouse for work, I bought a $10 GearHead LM6000U laser mouse—if I can't be happy, at least I can be cheap. Laser mice, as far as I can tell, all use much higher resolution imagers than their diode-equipped optical siblings. As a result, when I move my mouse an inch, my optical mouse registers a 400-pixel movement, but the laser sees 1600 pixels go by. This is great, except that my fine motor skills haven't magically improved by 4x just because I spent a Hamilton at Fry's. So just turn down the mouse sensitivity, right? Well, kind of...

X has an interesting way of doing mouse sensitivity. Basically, you say xset m <accel> <thresh>, and when your mouse moves more than thresh pixels in a "short period of time" (probably one or two mouse refresh intervals, but I'm too lazy to find out for sure), the movement rate is multiplied by accel. But what if you want to slow down the pointer instead? Well, accel can be a fraction (yes, you specify a fraction, not a float), and thresh can be set to 1, and then all mouse movements end up slower. But then you lose the whole long distance movement acceleration thing which is really the point of this setting.

Well, now that we know that, we have to look a little more closely at the way X interacts with the mouse driver. In most modern implementations, e.g., default Debian behavior, X gets input device information from hald via the evdev module and sets up your pointers, ignoring any InputDevice sections in xorg.conf. While this is all soft and friendly, evdev is still a bit sparse in terms of configurability.

The other option is to use the traditional mouse module, wherein you can specify mouse resolution and, more importantly, mouse sensitivity. To convince X to do this, however, you first have to tell it to ignore hald-detected devices, like so:

Section "ServerFlags"
        Option          "AllowEmptyInput" "false"
        Option          "AutoAddDevices" "false"
        Option          "AutoEnableDevices" "false"
EndSection

AllowEmptyInput disables the kbd and mouse drivers; AutoAddDevices is the setting that tells X to talk to hald. You don't actually need the third line; I just put it in there out of spite. You can see more about all of these options in the xorg.conf(5) manpage.

Now that X isn't autoconfiguring your mouse and keyboard, you're going to have to specify them manually... but you can handle that. The point for us is to enable the use of the mouse driver in an InputDevice section pointing to our nifty high-resolution mouse so that we can take advantage of that driver's greater configurability:

Section "InputDevice"
	Identifier	"Mouse1"
	Driver		"mouse"
	Option		"Device" "/dev/input/mice"
	Option		"CorePointer"
	Option		"Resolution" "1600"
	Option		"Sensitivity" "0.25"
	Option		"Protocol" "Auto"
	Option		"Emulate3Buttons" "no"
	Option		"ZAxisMapping" "4 5"
EndSection

Now our nifty mouse is running at its maximum resolution, but we're scaling down the movements by a factor of four so it feels the same as the old mouse. This means that there are 4x the number of mapped mouse motion pixels in the same distance across the screen, i.e., you have higher precision control over your mouse pointer by a factor of 4 (no claims here about the practical limit of such things... if you don't think you need this, why did you bother buying a laser mouse?). It also means that we can go back to our friend xset and use the long distance accelerator function.

One caveat (this one bit me!): you cannot have two different pointer devices set at two different sensitivities. Don't complain to me, that's how xorg works. If you have multiple pointing devices, the highest (numerically greatest) sensitivity setting provided will be used, meaning if you have another mouse and have forgotten to set the sensitivity option in its InputDevice section, the above snippet will seem not to work because the default sensitivity is 1.0.

Another comment: for various reasons (basically I want firefox to work correctly), I run gnome-settings-daemon even though I use fvwm2 and abhor desktop environments. If you use a desktop environment like gnome or KDE, it will very likely override your xset settings with the settings from whatever crappy mouse config applet you use. If you don't want this to happen, at least in gnome, you can use gconf-editor to set desktop / gnome / peripherals / mouse / motion_acceleration and desktop / gnome / peripherals / mouse / motion_threshold to -1; this will apparently prevent gnome from screwing with your settings. Then, of course, just call xset at login from your .xsession (or whatever you call it) file. Or just use your crapplet to set it up and get off my lawn.

(Lest you point and laugh at my fvwm2 use: come back and talk to me when your windowmanager's configuration file is written in a turing-complete scripting language.)


[ permalink | 0 comments (add one you lazy bastard!) ]

Sat, 18 Apr 2009

whitespace Nazis must die

How am I the only person who sees how retarded Python is? It is, no lie, the worst programming language ever created.

Seriously. This is a language for which scripts can go from working to completely broken because your text editor converted tabs to spaces or vice-versa. I can email a working script to you and have it arrive broken. Newsflash: no one bothers to preserve whitespace because you can't fucking see it. Differentiating between a tab and seven spaces makes you retarded.

If you program in Python and like it, you are dead to me. If I see you programming in Python, I will kill you. Seriously, if you see me walking down the street while you're programming in Python you best jump right in the nearest coffin, I don't care if it's your birthday and you mama needs the coffin 'cause she's dead.


[ permalink | 8 comments ]

Thu, 11 Dec 2008

shackleds' revenge

Some of you might have read about this travesty of education. As a concerned resident of Austin, I did my part to help correct this injustice by writing the following letter to the AISD ombudsman:

From: "Riad S. Wahby" 
To: ombudsman@austinisd.org
Subject: Austin teacher versus Free Software

Ms. Reeves,

I'm writing to you today on behalf of "Aaron," the student mentioned in
this article:
	http://linuxlock.blogspot.com/2008/12/linux-stop-holding-our-kids-back.html
To summarize: "Karen," Aaron's teacher, found him discussing and
distributing copies of the Linux computer operating system, and
responded by confiscating said copies and making outlandish and
factually incorrect claims concerning computer software in general,
Linux in particular, and the legality of distributing same.  I urge you
to familiarize yourself not only with the details of the article above,
but with the facts concerning the Linux operating system and Free
Software in general:
        http://en.wikipedia.org/wiki/Linux
        http://en.wikipedia.org/wiki/Free_software

Before I continue, I'll inform you of my qualifications and experience
in this matter: I am not at all affiliated with Aaron, Ken Starks, or
HeliOS Solutions; I hold a Master's Degree in Electrical Engineering and
Computer Science from the Massachusetts Institute of Technology; I write
Free Software, both as hobby and at times in the past professionally; I
am an avid Linux user nearly to the exclusion of all Microsoft products,
personally and on behalf of my employer---I am a Senior Integrated
Circuit Designer at Silicon Laboratories here in Austin; and like Aaron
I have experienced oppressive ignorance at the hands of primary-school
"educators."

I shall not bore you by fully deconstructing Karen's claims concerning
computer software.  However, please note the following:
        - Dissemination of Linux and related software at no cost is
          completely legal.  There are many organizations whose purpose
          is to package Linux in a user-friendly way and distribute it
          for free:
                http://www.debian.org
                http://www.ubuntu.org
                http://www.fedoraproject.org
                et alia
        - Most Linux-related software is distributed at no cost under a
          software license called the GNU General Public License, which
          requires distribution of human readable source code along with
          the software. For students who are learning about computers
          and programming, being able to examine and experiment upon the
          code underlying a piece of software is of paramount
          importance; thus, Linux and Free Software in general are
          superlative learning aids.
        - The claim that "no software is free" is so incorrect as to
          verge on frightening.  Linux and related software have become
          pervasive to the point where they are used in everything from
          cellular telephones and computer networking infrastructure to
          video game systems and vending machines---precisely because
          the software and source code are available at no cost.
        - Karen's claim that she "tried Linux during college" is
          dubious; more to the point, it's apparent that if she did so,
          she certainly didn't learn anything from the experience!  As a
          seasoned Linux user, the notion that Linux conveys a
          disadvantage is amusingly parochial (especially in light of
          the wide variety of applications in which it is being used).
          That Karen believes this is the case is evidence that she has
          already been surpassed in computer knowledge by her student---
          and doubtless this gap will only grow as Aaron continues to
          use Linux.

In light of the above, I strongly urge you to intervene on Aaron's
behalf; moreover, if necessary I will happily testify in this matter.
That your teachers are misinformed about matters beyond their ken is
hardly surprising; that they would overstep so far as to discipline a
student, confiscate his property, and engage in calumny as a result is
inexcusable.

Thank you for your time,

-=rsw

Bets on whether I get a response?


[ permalink | 0 comments (add one you lazy bastard!) ]

Tue, 25 Nov 2008

heavy irony

Today I stole a book on ethics.


[ permalink | 0 comments (add one you lazy bastard!) ]

Wed, 05 Nov 2008

democracy rules

I'm not normally a sentimental patriotic type, but spontaneous anthem choruses at 2a following an amazing and cathartic election night make me go all tingly.

This is the first time I've ever embedded a YouTube video here. Slouching Towards Gamorrah, certes.


[ permalink | 0 comments (add one you lazy bastard!) ]

Mon, 15 Sep 2008

ultimate rickroll

Last week, Jeff was out of the office on vacation. Since he'd previously pranked Ion, a few of us plotted to even the score. Stretch suggested that we take the MP3-filled 300Gb external hard drive on his desk and replace all the files with some godawful music. We settled on a slight modification of this plan: for each MP3, I took the first 5 seconds of the real song and pasted it onto the front of one of a selection of songs, including

  • "Ventolin"—Aphex Twin
  • "Heut' Ist Mein Tag"—Blümchen
  • "Rollerskate Date"—Group X
  • "Party 4u (Holy Nite Mix)"—Cranky
  • "Call On Me"—Eric Prydz
  • "Dragostea din tei"—O-zone (a.k.a., the Numa Numa song)
  • "Quit Playing Games With My Heart"—Backstreet Boys
  • "What Is Love?"—Haddaway
  • "The Sign"—Ace of Base
  • a few pieces of Romanian folk music provided by Ion
    and of course...
  • "Never Gonna Give You Up"—Rick Astley

As luck would have it, the first song Jeff chose to play had been stapled to "Never Gonna Give You Up"—a dead giveaway to him that something was very wrong. During testing, our favorite combination was "What A Wonderful World" cutting into "Heut' Ist Mein Tag".

I learned a few things from this. First, most MP3 players will barf if you give them an MP3 whose samplerate (not the bitrate, the samplerate of the decoded PCM stream) changes halfway through. This includes some versions of mpg123, iTunes, Windows Media Player, and WinAmp; mpg321 seems to work fine. Second, the quelcom package is very nice, comprising commandline utilities to cut and paste together MP3s without reencoding (and WAV files, too); if qmp3cut doesn't like an MP3 file, cutmp3 probably will. Third, id3cp (from id3lib) is very useful when you want to replace every mp3 on someone's hard drive without raising too many suspicions. Finally, in retrospect putting 10-20 seconds of the original MP3 rather than 5 would probably have been a little more effective on the confusion front.


[ permalink | 0 comments (add one you lazy bastard!) ]

Mon, 25 Aug 2008

semilunar hiatus

Or is it bilunar?

Anyway... I haven't posted in a while, so here's what's new with me:

  • About a month ago, we got a second dog! He's a Nova Scotia Duck-Tolling Retriever. His official AKC name is KD's Ten Thousand Gauss, but we call him Niko (shortened from Nikola Tesla. Get it? 1 T = 10 kG). Niko and Shockley are best friends, and while Niko will eventually be about twice Shockley's size (45 pounds versus 25), for now they're within a couple pounds of one another. To the right is a picture of him and Shocks eating.
  • I'm turning into a soccer mom.
    Well... not really, but I am trading in my beloved STi for a Volkswagen Jetta SportWagen TDi. Apparently I have a penchant for three letter trim designators ending in "i," but this time it's not a rice rocket—it's a diesel. The wagon (similar in size to an Outback, but a little tubbier looking) will hold the pups nicely, transport too many people to ridiculous parties, and carry three or four kegs in the back, all the while getting 50 MPG.
    I'm picking up the car tomorrow in El Paso (the diesel wagons are ridiculously hard to find because there are only like 2000 of them being made this year, so I've heard) and I expect to get back to Austin on one tank with fuel to spare. Eat that, Prius.


[ permalink | 0 comments (add one you lazy bastard!) ]

Tue, 24 Jun 2008

pix plz kthx

Here, you happy now?


[ permalink | 0 comments (add one you lazy bastard!) ]

Mon, 16 Jun 2008

broken promise of a thousand words

No pictures this time, patient readers. My apologies.

Well! We finally taped out the Thursday before last, so I was off all last week catching up with things around the house. The main event was setting up irrigation for my poor parched yard, which involved lots of soaker hose for all the planters and a few impact sprinklers for the grass. I have things divided into two zones on each of the three spigots placed around my house, and as long as I only run one of the two sprinkler zones at a time the water pressure is sufficient to run soakers on the other two spigots.

This strongly suggests my next project: none of the electronic timers I've found can be programmed for the odd watering schedule around here, viz., Wednesdays and Saturdays, so I'll just have to build my own. Either I'll make individual ones for each sprinkler, or I'll do a little control interface for some solenoid valves and hook it up to positron.

Speaking of positron, that was the other time sink this week: positron Mk. V died a slow lingering death. A couple weeks ago I started getting random lock-ups; figuring it was a heat problem, I reduced the CPU core voltage, and this seemed to work for a while. Unfortunately, it started happening again, and the frequency of occurrences increased to the point where it wouldn't even get through a boot sequence. I swapped video cards, pulled RAM, and even swapped the processor (since I found one for $20ish), to no avail. My last effort was replacing the power supply, since I figured if I had to replace the motherboard I'd need one anyway. Fortunately, Fry's had a sale on the Antec Neopower 500 (for $65, no less!). Unfortunately, the new supply did nothing, but that just meant that I had an excuse to build positron Mk. VI.

Initially I really liked the abit IP35-Pro, but decided that spending that much on a motherboard wasn't worth it unless I was actually planning on running a FSB upwards of 500 MHz. Instead, I ended up getting a DFI LanParty DK P35-T2RS, which is a reasonably priced board that's another favorite for dual and quad core overclocking. Since I'm kind of cheap, I only sprang for an Allendale E4600, which should overclock by 30% with relative ease; I figure by the end of the year quads will be even cheaper and I'll trade up. I also picked up 4 Gb of RAM (a new personal best!) and a reasonably-priced GeForce 8800 GT board (thanks for catching me up on the NVidia chipset line, Wikipedia). For now, Mk. VI will inherit Mk. V's RAID array, and yes, I'm still running Mk. III's 18 Gb IBM Wide Ultra2 SCSI drive as the boot drive. Pretty soon I'll go to a small (30ish Gb) 10k RPM SATA drive for the boot and get four 500 Gb SATAs for a new RAID5 array.

Since I'm talking about positron, I think it's time for a retrospective:

  1. 1994: Pentium 133 MHz, 8 Mb RAM
  2. 1997: Pentium-MMX 233 MHz, 40 Mb RAM
  3. 1999: Dual Pentium II 450 MHz, 512 Mb RAM
  4. 2004: (July) Dual Pentium IIIs at 1 GHz replaced Mk. III's processors
  5. 2004: (October) Athlon64 3200+ (2.2 GHz), 1 Gb RAM
  6. 2008: Core2 Duo E4600 (2.4 GHz), 4 Gb RAM

Just brings a tear to your eye...


[ permalink | 2 comments ]

Fri, 30 May 2008

A-team pipevine dream

Phew, busy! It's tapeout season, so layout is life, and life less than layout.

A couple weeks ago one of the Pipevine Swallowtail caterpillars made his chrysalis on the frame of the porch door. I couldn't resist taking him inside and painstakingly hanging him with dental floss and tape from a piece of cardboard that I perforated and cut to fit in place of a mason jar lid. Well, last night my "hard" work paid off—he emerged! (Yes, "he," I checked the markings.) I know, this thread is worthless without pics. Sue me, my real digital camera wasn't charged and my phone has no flash, so taking pictures of him at night before letting him outside for his wings to dry wasn't happening.

Second... virtual insanity. Okay, not really, but another animal! Well, two, kind of. My younger sister moved to Austin, so she's going to stay at my house at least for the time being. With her came Hank, who is now Shockley's new best friend. I'll get pictures of them playing ASAP.

The other new animal was, erm, unexpected. Katherine and I talked a long time ago (before we got Shocks) about getting another cat, specifically a Turkish Van—a crazy swimming cat! Of course, we decided to get Shockley instead, so that never materialized. Well, a few days ago I was just randomly browsing through the Town Lake Animal Center website and was astounded to see that someone had turned in a Turkish Van!

It turns out that her elderly owner had died and passed the cat to one of her children. Unfortunately, they didn't want the cat because the kids were allergic, so they brought it to the shelter. Well, I figured I'd just go down and see this cat, mostly to meet one in person lest I decide in the future to get one. Upon further inquiry, it turned out that she'd already been there a month with absolutely no interested visitors (it's kitten season; everyone's going for a baby), and she was sad and emaciated. Long story short, she was super friendly and polydactylic (6 toes all around) and I'm a huge sucker. Oh yeah, and TLAC has to kill about 70% of the animals that end up there due to over-crowding.

We decided to name her Inara because the breed is from a region of Turkey that was ruled by the Hittites at one point. Also because we're nerds, Firefly is awesome, and Katherine insisted that Mnemosyne was too clumsy. I'll have more pictures up later; for now, here's her shelter portrait:


[ permalink | 2 comments ]

Wed, 21 May 2008

absentee blog-lord

Tapeout is getting in the way of entertaining you, faithful readers. Apologies.


Best of friends.

Ninja cat hides in bush.

Why do they have to do it on my porch?

I've got a bunch of Pipevine Swallowtail caterpillars in the yard.


[ permalink | 1 comment ]

Wed, 23 Apr 2008

hey Hillary


[ permalink | 0 comments (add one you lazy bastard!) ]

Wed, 16 Apr 2008

T + 12 weeks

See, he can stand up:


"I know kung fu."


"Show me."


pwned


[ permalink | 1 comment ]

Sun, 30 Mar 2008

weekend update

New pictures of the little one:


Loving that pig's ear.

Tired after herding the soccer ball.

What? I ain't sayin' nothin'.


[ permalink | 3 comments ]

Mon, 24 Mar 2008

puppy update

I got the puppy Saturday as planned; he's adorable and very smart. In the end the names came down to Shockley or Tycho, and I decided to go with Shockley despite Katherine's preference for Tycho.

I'm not 100% sure yet, but I'm leaning towards feeding him a raw diet because it's better for him, I have backyard space in which to feed him, and he doesn't seem altogether impressed with dry food at the moment.

Meanwhile, the cats are divided in their reaction. Anya is just pissed that we brought another thing into her territory (especially at me, because I'm the one who carried him into the house). If I go near her she'll grumble audibly, and if I pick her up she'll yowl and even hiss. She's not actually all that scared of him: she walked right up to him and sniffed him before deciding he was the enemy. Dinah, on the other hand, is a bit more affectionate since we brought the dog home, presumably in a bid to keep our attention. Meanwhile, she seems like she's trying to work up the courage to play with him. My guess is they'll eventually be best buds.


[ permalink | 2 comments ]

Thu, 20 Mar 2008

my new best friend

This Saturday I'm finally going to exercise one of the privileges of having a fenced back yard and my own house: I'm getting a puppy! That's him on the right. He's a Pembroke Welsh Corgi and is 8 weeks old today.

Though I'm not 100% on the name yet, I believe the leading candidate is Shockley (especially since this has been my planned dog name for approximately forever). Other possibilities include Ampere, Faraday, Heaviside, and Rayleigh. Also, since he's Welsh, I'm considering Aneirin. Katherine has suggested Thorin (since "Corgi" is believed by some to be derived from the Welsh phrase for "dwarf dog"), Panama (imagine yelling after your dog in your best David Lee Roth impression), and Goro, but I'm not particularly partial to any of them.

Obviously I'll post more pictures as soon as they're available (hopefully ones where he looks less like Tommy Chong after a bender). In the meantime, please cloud the name issue with more suggestions!


[ permalink | 0 comments (add one you lazy bastard!) ]

Sun, 16 Mar 2008

can you back it up? no, no, that box... back it up

After a hard drive crash scare on proton (my colo machine) earlier this week (no data lost, fortunately!), I decided it was time to get serious about regular backups.

I did a bit of research and initially settled on Bacula, but because of licensing issues the Debian packages do not link to OpenSSL. This means that I can't encrypt even the handshaking, let alone the data transfer, between client (proton) and backup server (positron).

After a little more searching, I found BoxBackup, a solution geared towards backing up across a WAN. It uses SSL/TLS authentication: the server has a signing key and clients must generate keys and then have them signed with the server key before they can connect. On top of that, each client has another key it uses to encrypt the data it stores on the backup server so that it's transmitted and stored securely, and clients can be sure that their data is secure even from the backup server's admins.

Setup was a breeze (somewhat simpler than Bacula, though neither is particularly difficult), and while the initial 1.6Gb of data was somewhat unpleasant to transfer over my DSL connection, I expect that the incremental change data should not unduly load my network connection.

Now go set up your backup server already.


[ permalink | 2 comments ]

Wed, 05 Mar 2008

adventures in democracy

or, Precinct Captain Sam(ir)

Yesterday was primary day here in Texas. Most of the time the primary results here are meaningless, but this year the Obama-Hillary race is hot and every delegate counts. Thus, I was determined to do my civic duty and vote. Early in the morning, after dropping Katherine off at her lab, I headed to the middle school near my house that served as the voting place for my precinct. Unfortunately, when I got to the head of the line, it turned out that I was still registered in a different precinct—the one I'd been in last election, a 20+ minute drive away. I determined that I'd go vote around 6:00p and wait around to take part in the caucus at 7:15p (yes, Texas has both).

I arrived at the polling place around 6:30p, well in time to get in the doors (which closed at 7:00p) and vote. Since there were only three voting machines, the people who were in the voting place at 7:00p took until almost 8:00p to finish their voting. After that, we waited for over an hour before they were finished "closing the books," as they told us. Apparently some time during that hour they got scared that the 150 people waiting around to caucus would get rowdy, because 6 police officers showed up—you know, to keep the peace.

Now it got interesting. The dude came out with the caucus folder and asked who the Precinct Chair was. Turns out, there was no precinct chair, at which point it became rule of the unlame—in this case, me.

After appointing a Secretary pro tempore, deputizing a bunch of people to run the sign-in sheets (despite starting almost 2 hours late, we still had over 100 people caucusing!), and getting everyone organized and signed in, I explained the process of the caucus meeting to everyone and (as prescribed by procedure) called for the election of a new Chair and Secretary. Now, whereas I was pro-Obama and our temporary Secretary was pro-Clinton, the roles switched: the Chair was a Clinton campaign volunteer (who turned out to be a nice guy once he calmed down a bit) and the Secretary was pro-Obama. Such was the tone for the rest of the meeting: I worked through the sign-in sheets checking voter ID numbers, counted the votes, and computed the delegates, all with oversight from the Clinton camp. Then a Clinton person independently verified my results with oversight from an Obama supporter.

Things got a little hairy because we couldn't verify the identities of two of the people who had signed in, but I moved successfully that we compute everything with and without those two votes to determine if it made a difference in how the delegates were assigned. If it did not, we resolved, we would simply count them (to avoid having to go through the process of striking votes) and proceed. Luckily, the delegates were the same by both counts.

Finally, we got to the fun part: picking the 8 Obama and 5 Clinton delegates to the county caucus (plus alternates). By then we were down to fewer than 30 people, so it was really just a matter of determining who wanted to be a delegate and then convincing the rest of the people that being an alternate probably wouldn't actually entail any work. At midnight—three hours after starting the whole process—we'd finished.

Who knew that dispensing democracy would remind me so much of running a Random Hall general election? For that matter, who knew Robert's Rules of Order would come in handy when arguing with anyone other than Roger Ford or JHawk?


[ permalink | 1 comment ]

Fri, 29 Feb 2008

white event

Tonight I was playing around with Octave et al studying the frequency content of sequences generated by a 16-bit LFSR as a function of its feedback polynomial. Using a random selection from Philip Koopman's list of feedback polynomials that produce maximal 16-bit LFSRs, I generated the corresponding sequence and plotted its FFT in Octave.

What I found, effectively, is that more terms in the feedback polynomial whitens the sequence rather substantially. For example, a short feedback polynomial (0x8148) produces the following spectrum:

On the other hand, the spectrum for 0xfff6 looks like this:

This suggests that feedback polynomials with lots of terms are better for dithering sequences. The downside of this, of course, is that each term requires an additional XOR. Fortunately, if you use a Galois LFSR the computation delay is independent of the number of terms.

In case you're curious (more or less identical to what's in the Wikipedia article):

#include <stdio.h>
#include <stdint.h>

int main(int argc, char **argv)
{
        uint16_t poly;
        uint16_t lfsr = 1;
        uint16_t period = 0;

        if (argc > 1) { poly = (uint16_t) strtoul(argv[1],NULL,0); }
        else { poly = 0xb400; }


        do {
                lfsr = (lfsr >> 1) ^ (-(lfsr & 1) & poly);
                printf("%d\n",lfsr);
        } while (lfsr != 1);
}

All the data, code, et cetera is also available.


[ permalink | 1 comment ]

Mon, 11 Feb 2008

coincident queuage

Over the weekend I finally took the time to code up a little hack to use my AirLinkTek MediaGate MG-35 as the playback mechanism for MP3q. Basically, my solution was to keep the MP3q server running on positron, but to configure the playwrapper.sh script (for those of you who have jacked around with MP3q in the past, you know what I'm talking about) to connect to the MG-35 and start playback.

The default MG-35 firmware has no means by which to do this, but the kind folks over at the mg-35_firmware_mods Yahoo! group have a hacked version that runs a telnet server. Naturally, I'm lazy and don't want to assemble a MIPS uClinux build toolchain, so I just had to make playwrapper.sh smart enough to connect, make sure that positron was mounted, and start playback via telnet. Simple! (A good bit of information about the mp3 player executable on the MG-35 was also gleaned from the mediagate wiki.)

In case any of you want it, you're welcome to the whole MP3q shebang. I'm not really interested in providing tech support for it, so probably if you write to ask questions I'll just berate you for not "getting it." Or maybe just ignore you. Something like that.

As for strange coincidences: my blog is configured such that it always shows the 25 most recent entries on the front page. As a result, each post bumps an old one off the bottom of the list. Strangely, the post that this one is bumping off the post from a bit over a year ago wherein I mentioned that I had found the MG-35 and was intending to make it work with MP3q. A year of good intentions later, it's quite a surprise I'm not already in hell.


[ permalink | 0 comments (add one you lazy bastard!) ]

Sat, 09 Feb 2008

voyage of rediscovery

So it turns out that my discussion yesterday is (as you would expect) a well known one among those who build digital filters. There is even some terminology to go along with it.

The representation of numbers as plus or minus a fractional power of two is effectively canonical signed digit representation, and while my algorithm doesn't explicitly guarantee canonical results, it does so implicitly by minimizing the (log-wise) error in each step. It should be obvious that CSD is more efficient than two's complement at representing numbers, since digits are ternary (0,+,-) rather than binary.


[ permalink | 0 comments (add one you lazy bastard!) ]