The Fugue

Counterpoint by Hans Fugal

Clojure DSP Longing

Posted by Hans Fugal Mon, 17 Nov 2008 17:46:00 GMT

I often find myself longing to be able to use Clojure, a very enticing lispy language that runs on the JVM.

I could possibly be using it right now in my dissertation research. It has the promise of dynamic languages, functional programming, almost-as-cool-as-Erlang concurrency, JVM performance, and Java library soup. It could be so awesome. A few months ago I started briefly down this road, unaware that…

Clojure sucks. Not generally, but it sucks for DSP. More specifically, Java and therefore Clojure has no real support for complex numbers. In order to do serious DSP, you need native syntactic, semantic, and performance support for complex numbers. Java has none of the above. Older versions of C didn't have syntactic or semantic support, but the performance of using arrays was plenty fast. Not so in Java, at least not to the extent necessary to override the lack of syntactic and semantic.

So someday, when I'm writing general purpose code again and not high performance DSP code, I will have an opportunity to use Clojure, and I think that will make me very happy. By then the book will be out of beta. The community will be in full swing. There will be awesome libraries. Children will play in pristine parks with formerly-ravenous ravens.

In the meantime, if anyone sees the scene change, do let me know.

no comments |

Gnuplot in Action

Posted by Hans Fugal Mon, 22 Sep 2008 22:21:00 GMT

One of the oldest and most universally useful tools we have is gnuplot. It is also one of the least understood and most underutilized tools we have.

I can hear you now. "What do I need gnuplot for? I don't make graphs." Well that's exactly the problem. Everyone who works with data should be making graphs, and lots of them. Do you write programs that manipulate data? You need gnuplot. Do you want to evaluate performance or traffic on your website? You need gnuplot. Do you want to impress your friends with cool graphs of the growth rates of yeast and bacteria in sourdough or your weight loss and percent body fat? You need gnuplot.

I've been using gnuplot for years. I scraped up enough gnuplot skillz to make basic graphs and it has been invaluable. But I knew gnuplot could do more than I knew how to make it do, and whenever I tried to do something advanced it was only with great pain that I succeeded. Often I failed. Let's face it, gnuplot can be a bear to learn. Why? Well, mostly because of the documentation. Not that there isn't any, almost the contrary. There's a lot of documentation, but it's very much reference documentation. What the world has been lacking is a good introduction to gnuplot that isn't afraid to get nitty-gritty where it needs to, but doesn't just parrot the abundant but obscure documentation that's already out there.

We no longer need to wait. The book is called Gnuplot in Action by Philipp Janert, and it is an absolutely fantastic book. Really, I can't say enough good about it.

Janert walks the fine line between cheesy tutorial and dense reference with the skill of a circus acrobat. The writing is approachable, yet chock full of useful information. Nothing is rushed, but it doesn't plod. The text is sprinkled with beautiful graphs that expand your imagination and open your eyes to the possibilities of gnuplot.

In chapter 2, "Essential Gnuplot", the impatient reader is given a whirlwind tour of gnuplot basics. After just 11 pages you will know everything you need to know for 90% of the graphs you will ever need to create. In fact, you'll know more than I knew when I began reading it—I learned a couple things that I kick myself for never having discovered on my own.

Chapter 3 goes into more detail on dealing with data, and in that chapter I learned a ton. Several of the things I learned in this chapter have saved me numerous hours this semester alone. Chapter 4 picks up the remaining miscellany.

In part 2, all those nagging questions of polish are addressed. This is where I used to spend the most time banging my head against the wall, searching, plodding through various newsgroup threads. "How do I get this or that to look just right?" These types of questions are hard to find answers to in search engines. Janert takes us by the hand and explains each and every question I've ever had and a few I hadn't yet dared to have. Truly beautiful graphs are now within my grasp. What's more, it no longer seems like an exercise in pain but a simple recipe for success. After Janert explains these techniques they seem plain as the nose on your face, yet he's not condescending.

Part 3 dives into the deep dark secrets of gnuplot. 3D plots, color, multiplots, different coordinate systems, fitting, terminals, and a dozen other things you didn't even know that you didn't want to know. No doubt you'll skim this section the first time and come back to it when you need those dark magic tidbits.

Part 4 is arguably the most important part of this book, or perhaps second after part 1. Part 4 is a crash course on graphical analysis. What kinds of graphs you can create, when you should and shouldn't use them, how not to lie with graphs (and how to pick out people lying with graphs), and most importantly, how to go from raw data that you don't understand to organized data that you do understand and have pretty graphs to demonstrate to boot. All with practical examples that you can tweak for your own use.

Finally, there's a gnuplot reference in the appendix. This is a deluxe package and has everything you need to become a gnuplot guru. I am thrilled that this book is coming to dispel the darkness surrounding gnuplot.

I really have no cons to speak of, other than the prerelease PDF I had access to had some minor problems—the sort of problem I would expect to be resolved in the final stages of editing. I don't have experience with other Manning books, but having seen prerelease versions of other books from other publishers I'd say the current copy is par for the course. I'm certain they'll fix those things up and have an outstanding PDF in the end. I recommend springing for the dead tree version though, as I expect the reference at the end of the book and the examples throughout will be more accessible next to your computer instead of on the screen. (You already use quite a bit of real estate running gnuplot and/or editing a gnuplot file and displaying graphs.)

2 comments |

Touch Typing

Posted by Hans Fugal Thu, 11 Sep 2008 19:14:00 GMT

Steve Yegge has posted an funny, irreverent, and above all excellent argument for touch typing. I highly recommend it even if you do touch type.

I am downright flabbergasted by some of the comments though. There are hunt-and-peck folks defending their inability to touch type as lifestyle choice based on the belief that they will get RSI. People justifying typing slow because it saves them from wasting time chatting or writing long emails. There are some interesting claims from 2–4 finger typists that they can type without looking at 70wpm (this is certainly possible), and choosing not to learn to touch type the "right way" because it will give them RSI (this is certainly ludicrous).

Typing is a vital skill if you work in IT, especially programming. Of this there is no doubt, rationalizing strangers aside. I simply cannot imagine being stuck typing at 10wpm or less. It would be like being stuck behind a pair of tractors on the freeway going 20 mph. For the rest of your life.

Last I checked I type about 65 wpm on average. I could probably go faster, but I never have felt the need. I can type as fast as I think when programming. If I were a stream-of-consciousness novelist or a secretary, I could probably make use of a faster typing speed. As it is, 60–70wpm seems to be a sweet spot for me.

I'd like to discuss the ridiculous RSI claims. Yes, if you type all day without breaks you can get RSI. There are certain things you can do to mitigate or exacerbate this for a given amount of typing and typing speed. If you tried to go lightning fast all the time you might hasten the onset of RSI. But I argue that the absolute worst thing you can do if you're afraid of RSI is to not touch type. RSI means Repetitive Stress Injury, from repetitively performing certain motions until your body starts to break down. Smaller more relaxed motions are less stressful on your body than large stiff motions. If you touch type well, your hands are relaxed, your fingers float over the keys, and movement is minimal. Of course you still need to take care—take breaks, spend some time thinking without typing or drawing pictures on paper, proper nutrition, etc. But the biggest thing you can do to prevent RSI is to have proper form. And maybe learn dvorak (I still use qwerty because I find sysadmin and programming to be tedious with dvorak, but I don't spend most of my time actually typing).

On the other hand, if you hunt and peck 24/7 guess how much more movement—repetitive movement—your body is enduring? Ever heard of tennis elbow? RSI isn't the exclusive privilege of touch typists. If you type slow enough that you can't possible get RSI, you are irrelevant. If you type fast enough to be productive but don't have good form, you are setting yourself up for RSI. If you're RSI-prone or just paranoid, go learn dvorak now or find a job that doesn't require much typing.

I'd add to Steve's exhortation to learn to touch type, that if you do touch type but you feel your form is off, you have low accuracy, or you feel that your fingers are stiff, do some conscientious practice. Focus on accuracy and relaxation first, then speed. Enhancing your typing skills is a great benefit if you spend a lot of time typing, although learning to touch type in the first place is obviously a much bigger payoff.

Let's continue to learn from musicians: correct form (including relaxed posture and keep those wrists off the keyboard/desk), accuracy, then speed.

1 comment |

Fixed Point for Sysadmins

Posted by Hans Fugal Fri, 09 May 2008 14:31:00 GMT

In CS language theory we sometimes talk about fixed points. Everyone seems to have a bit of a hard time understanding what a fixed point is at first, and I thought of an interesting analogy just now that will make sense to sysadmins.

When you go to install foo, with apt-get install foo, apt will tell you all the dependencies it will install, and it will also tell you the recommendations and suggestions, then ask for your permission. You might decide to say no and repeat the command with one or more of the suggestions added. Then it will do the same, but now with the suggestions of the suggested packages as well. You might repeat a couple of times. Finally, you will be happy with the selection of packages you're going to install. You've found the fixed point.

Apt itself does the same thing when resolving dependencies. If you remember rpm-based distros before apt-alikes, you used to have to find the dependencies fixed point by yourself. We called this rpm hell for good reason.

So when you're finding a fixed point in math, you're doing a similar thing. You're repeatedly performing the operation until further operations don't change the answer. The fixed point of a function f(x) is x0 such that f(x0) = x0.

no comments |

Functional Floundering

Posted by Hans Fugal Sun, 06 Apr 2008 23:21:04 GMT

Levi pointed me to a presentation on Clojure, "a dynamic programming language for the JVM". That's actually a pretty bland description. I'd describe it at least as a dynamic functional concurrency-oriented lispy language for the JVM. The presentation was interesting, though I wish I had been able to follow the ant colony demo (it's audio-only).

It awakened the oft-recurring "functional floundering" feeling. I've written a semester worth of scheme in a programming languages course. I've read the Erlang book and written a little Erlang code. I recently went through a graduate course in programming languages with emphasis on denotational semantics. I understand the lambda calculus, functional programming, etc. But I feel completely stymied whenever I think about actually programming in a functional language.

I'm not sure what the root is, but I'm sure it boils down to lack of practice. That undergraduate course aside, I haven't had any practice. And since that course was very handholding (too much in retrospect), I don't feel like I took any practical skill away from it. Yet I feel that in the future functional programming for concurrency will be important, even if I'm not convinced it will be essential.

So I don't have time right now to really rectify the situation, but that doesn't stop me from wondering—how does one learn practical functional programming? What problem sets do you work through to get the needed practice? I suppose the question can apply to learning any new language, but there is much paradigm carry-over between imperative languages (and probably between functional languages). Are there certain problems that will aid that paradigm shift? If you feel like you've developed functional chops, in any functional language, I'd like to hear in the comments how you got there, what you'd change in retrospect, and your advice for me and others like me.

1 comment |

Network Programming

Posted by Hans Fugal Sun, 16 Mar 2008 15:44:54 GMT

If ever you find yourself wanting to do some network programming in C, C++, or any other language that uses the socket paradigm, you must be careful. You are only inches from the edge of the precipice of insanity.

Luckily, some guy who calls himself Beej wrote a fantastic guide to network programming. He takes you by the hand and leads you gently away from the precipice. His guide is fun and easy to grok, but doesn't water the topic down. It's a fine piece of writing.

Even if you're writing Ruby network code, for example, which streamlines much of the insanity (thanks to exceptions and some nice OO abstractions like TCPServer), the socket concepts you will gain from at least skimming this guide will be a huge help.

no comments |

Computer Music Seminar

Posted by Hans Fugal Wed, 01 Aug 2007 17:04:33 GMT

Today I presented a 1-hour seminar on Computer Music to a summer camp group here at New Mexico State University. We talked about what we can do with computers, demonstrated Ardour, Audacity, and GarageBand, and had a good listen to a few quality pieces. We even mentioned U2.

My presentation is available as a PDF, and it has links to all the interesting sites we mentioned. For those that weren't there, I'd like to point out especially Real World Remixed where you can download sample packs for some great music, including Peter Gabriel and Afro Celt Sound System songs, and remix them yourself with something like Ardour. Hours of fun!

no comments |

Implementing State Machines

Posted by Hans Fugal Tue, 31 Jul 2007 04:40:00 GMT

The lowly state machine, aka finite automata, is a beautiful and useful thing, on paper. But when it comes time to code one up, things can get ugly. You see, any first-year CS student can code up a state machine in the naïve way—with a state variable and a big nested while/case/if mess. It's hard to read, it's tedious to code, and it's very easy to get yourself all wet if you're not careful. Then there's the state transition table where you put all the state transition information in a hardcoded table, or in a source file that you write a program to generate the static table from, or if you're really fancy you read the source file at runtime. These get uglier than ugly, real fast.

I've always known deep down that there must be a better way to write state machines, at least in languages with the necessary niceties. I've implemented a number of semielegant state machines, but never really felt I hit on the One True Pattern™. Speaking of patterns, the Gang of Four have a state pattern for overengineering state machines with the magic of object-oriented programming. It's definitely more OO than the traditional approach. Probably one of the better ways to do it in C++ or Java. But let me share with you what I figured out in Ruby this evening.

Disclaimer: I'm probably not the first to come up with something like this, but I didn't see anything in my feeble attempts at googling state machine implementations. Second disclaimer: this is an agile state machine pattern; it doesn't concern itself with being bulletproof, all-encompassing, or high performance. But it's dead simple, very little code which is very easy to read, very flexible, and elegant. You and I should be able to adapt it to our needs easily many times over.

Here's a sample state machine, and the code for implementing it (in the code I add arbitrary final states and a transition action for demonstration purposes):

Transducer

  require 'dfa'

  d = DFA.new('A', ['A','C'])
  d.transition do |s,a|
    ss = case [s, a]
         when ['A', 0]: 'B'
         when ['A', 1]: 'C'
         when ['B', 0]: 'B'
         when ['B', 1]: 'C'
         when ['C', 0]: 'D'
         when ['C', 1]: 'C'
         when ['D', 0]: 'A'
         when ['D', 1]: 'C'
         else raise "Invalid transition (#{s}, #{a})"
         end
    print ss
    ss
  end

  ary = [0,0,0,1,1,1,0,1,1,1,0,0].map do |a|
    d.eat a
  end
  puts
  p ary

The file dfa.rb which contains the DFA class is straightforward too.

Notice how you're free to implement the transition function however you like, e.g. by parsing a config file or hardcoding a state transition table, or clumping things together in an intuitive or even metaprogramming way if you have a lot of similar transitions. Notice that you don't have to do formal dances like defining the set of states explicitly, but the underlying theory is sound. Notice how you can get the input any way you please, and feed it to the state machine one piece at a time. Nothing is holding you down, you are free! And yet none of these things is in the least bit harder than if you hadn't used it. It's helpful but transparent. It is cuter than your cat and more loyal than your dog. Ok, I'll stop now.

The basic pattern is, in case you haven't been reading the code and documentation (ahem), abstract away the state-tracking stuff into the DFA object; provide the transition function which aligns nicely with theory (d: S x ∑ → S), and we'll look the other way if you sneak some transitional actions in there; and provide the input loop. All you really need in your pet language is first-class functions. Duck typing would (as always) be nice too, because then your states can be meaningful objects, eliminating an extra layer of indirection. It might not turn out as pretty in your language, but it would be as flexible and DRY.

Extending this to nondeterministic finite state automata wouldn't be hard, either, if that's what you need.

If you have a better way to do state machines (or a pretty-good way in $your_favorite_crippled_language), do tell in the comments.

Posted in | 4 comments |

ICMC 2006

Posted by Hans Fugal Sat, 16 Sep 2006 23:16:10 GMT

My GAANN fellowship will be sending me to New Orleans in November for the International Computer Music Conference (ICMC). I'm pretty psyched about this. I've never been to an academic conference, and I've certainly never been to a conference about Computer Music. It's going to be a blast, and it's going to be very informative. Hopefully I'll be able to network with some people in the field working on research similar to my own (which will begin in earnest in January, since my coursework is (almost) done after this semester). There will be Computer Music conferences, and I'll be sure to catch some good old New Orleans Jazz too.

I haven't asked yet, but I'm hoping GAANN will send me to the Linux Audio Conference in Berlin next year, too.

no comments |

Duck Typing Defended

Posted by Hans Fugal Sun, 09 Jul 2006 00:21:00 GMT

Ever since I discovered ruby I've loved dynamic typing. I never paid much heed to people who got their knickers in a knot over how dynamic typing is "unsafe".

While working on Ardour this summer, I've literally been wrestling with C++, all because it is statically typed. The code I've been writing over the past month could have been done in one week with half my brain tied behind my back (which is the usual situation, by the way), if only C++ were dynamically typed.

In other ways static typing hasn't exactly got in my way, it just causes me to jump through hoops that seem silly, unnecessary, and inelegant. A simple concrete example will help. I'm doing undo serialization, and of course Ardour already serializes other things in order to save sessions. In C++ this means lots and lots of otherwise unrelated things all inherit from a common serializable base class. This is why multiple inheritance is necessary in C++. In Java you can use interfaces, which is better than multiple inheritance but not by much. In dynamic languages, you don't even have to give it a second thought. You just make sure everything that needs to be serialized responds to a serialize method, et voilá!

So as I've been wrestling I've had this nagging feeling that it's *me* that's broken, not C++. Have I become so spoiled by dynamic languages that I can't program efficiently in a static language anymore? Are the static people right and one day my whole world will come crashing in and all my ducks will keel over? Feelings of self doubt are part of being human, and these were some of mine this summer. Then I read a blog post by Bruce Eckel on Strong Typing vs. Strong Testing and my mind was put at ease. The thrust is, dynamic typing is good, and testing is necessary. I think this quote about Robert Martin (a C++ guru) sums things up nicely:

Robert came to more or less the same conclusion I have, but he did so by becoming "test infected" first, then realizing that the compiler was just one (incomplete) form of testing, then understanding that a weakly-typed language could be much more productive but create programs that are just as robust as those written in strongly-typed languages, by providing adequate testing.

I have a thought along these lines. Let's say you've got duck typing in full swing as in his examples. Now in the real world it sometimes happens that you choose a common ambiguous word for the duck method, like "run" perhaps, but more often than not you have methods that are named fairly specifically, like "speak" or "jump". The static argument is that you might accidentally call the method on something that won't do what you anticipate because it's not of the right type. But really now, how many of your objects that implement "jump" are going to be the wrong kind of objects in your application? Often the answer is none. So you jump through hoops for no reason.

Do read the article, it's fun and well-written. Even if you come out still clinging to your beliefs that static typing is Good and Wholesome, at least you'll see that us dynamic people aren't necessarily lazy, stupid heathens.

Posted in | 2 comments |

Older posts: 1 2 3