Archive for March, 2009

C Is Not MATLAB

Refactoring some code at work today, I came across a classic example of somebody attempting to use one language like another. The project in question is a port from MATLAB to C, and the purpose of the function is to see if a square matrix is symmetrical within a certain tolerance.

The implementation I replaced worked somewhat like this:

int check_symmetry(double *mtx, int n, double tolerance)
{
    /* Allocate memory to work in */
    double *mtx_trans = (double *) malloc(n * n * sizeof(double));
    double *mtx_diff = (double *) malloc(n * n * sizeof(double));
 
    /* Matrix transpose */
    matxtrans(mtx, n, n, mtx_trans);
    /* Matrix subtract */
    matxsub(mtx, n, n, mtx_trans, n, n, mtx_sub);
 
    /* Assume matrix is symmetric to start with */
    int symmetric = TRUE;
 
    /* Iterate through rows */
    for (int i = 0; i < n; ++i)
    {
        /* Iterate through columns */
        for (int j = 0; j < n; ++j)
        {
            /* Was the difference greater than the tolerance? */
            double val = mtx_sub[i * n + j];
            if (fabs(val) > tolerance)
            {
                /* Exception found: matrix not symmetric
                 * (but notice that we keep looping...) */
                symmetric = FALSE;
            }
        }
    }
 
    /* Clean up memory allocations */
    free(mtx_trans);
    free(mtx_diff);
 
    /* ... and return the result */
    return symmetric;
}

Now, what this is really doing is the equivalent to the following line of MATLAB:

symmetric = max(abs(mtx - mtx')) > tol;

This in itself highlights the massive differences between MATLAB, where matrix operations are fundamental, and C, where they are not. While the above C code gets the correct answer, it’s far from efficient. What should be obvious is that the programmer translated the code, not the meaning.

To analyse this simple case: a symmetric matrix is reflected in the diagonal—the lower triangle is the same as the upper. What we really are trying to find out is if any elements violate this constraint. More verbosely: “does any element in the upper triangle differ from it’s corresponding element in the lower triangle (by more than a certain value)?” Once we’ve figured this out, the operation in C is much, much shorter:

int check_symmetry(double *mtx, int n, double tolerance)
{
    /* Iterate through upper triangle only */
    for (int i = 0; i < n; ++i)
        for (int j = i + 1; j < n; ++j)
            /* Compare to lower triangle */
            if (fabs(mtx[i * n + j] - m[j * n + i]) > tolerance)
                /* Exception found: matrix not symmetric */
                return FALSE;
    /* No exceptions found: matrix is symmetric */
    return TRUE;
}

This achieves the minimum number of iterations and element accesses by ignoring the diagonal, only iterating through the upper triangle and reversing the indices to access the lower triangle. The only potential downside is that it’s not as obvious what’s going on, but that’s what comments are for!

The lesson is that you should always make sure you’re using the correct method for the tool, and not trying to hammer a screw in with a spanner.

Persistent Remote irssi Session

I’ve recently moved back to using irssi as my IRC client, because when combined with GNU screen it can be kept independent of a graphical session, or even better, of a particular client machine (if you have a server somewhere). Since I have a home fileserver at the moment, I want my IRC client to always be running there. However, my usual workflow to do this is to open a terminal, SSH to the server, resume screen, move the window and resize it. This is far from optimal for something I usually want open…

Instead, I pieced together a command that I can use as a panel shortcut to do it all for me:

$ gnome-terminal --geometry 100x30-0-0 -x \
        ssh <hostname> -t "screen -D -RR -S irssi irssi"
gnome-terminal --geometry 100x30-0-0 -x
Open “gnome-terminal” at the bottom right of the screen with a size of 100 characters by 30. Run the rest of the command inside the terminal.
ssh <hostname> -t
Connect to <hostname> and execute the supplied command in an interactive pseudo-TTY.
screen -D -RR -S irssi irssi
Do whatever necessary to gain control of the “irssi” screen session if it exists, otherwise create it and run irssi inside it.

MPD + PulseAudio + Ubuntu Intrepid (8.10)

Update (2009-04-12): It appears that in Jaunty everything now obeys the system-wide setting properly, so you only need to edit /etc/default/pulseaudio and add the user to pulse-access.

I’m a big fan of Music Player Daemon (MPD), and up until the last few months I used it almost exclusively.  It’s lightweight, it’s good at what it does, and there are a lot of different frontends available.  One of the things I like most is that it’s not tied to a graphical session in any way—you don’t need a GUI open for it to be playing music.  Normal usage of MPD involves it being started and stopped as a system service.

Unfortunately, this doesn’t play too nice with the concept of how PulseAudio should be used.  PulseAudio is very user- and session-centric, and the recommended setup means than when nobody is logged in, no sound is going to be playing.  While MPD is capable of playing to a PulseAudio server just fine, having the sound server tied to the graphical session means it doesn’t have a sound device to attach to at boot, and the sound device suddenly disappears if the user logs off.

Ubuntu has used PulseAudio for as many applications as possible by default since Hardy (8.04), and while it can be removed, doing so can make life difficult.  This led me to pursue the option of a system-wide instance which everything uses, and which is always running.  But no matter how hard I tried, I got stuck with the same bug: starting GNOME would always result in a per-session instance being spawned in addition to the system-wide one, the two would fight over the sound card, and I would have to manually kill the new one every time I logged in.  Eventually I’d had enough of this and started using something else.

Today, I decided to take another stab at getting this set up properly and finding out where that second PulseAudio instance was coming from.  Thanks to the help of a couple of people in #pulseaudio on FreeNode IRC, I was able to figure out how to do this, so here is the method I used for the benefit of anybody else in the same position.

Stop PulseAudio spawning per-session

By default PulseAudio puts a script in /etc/X11/Xsession.d which causes a “pulseaudio” instance to be spawned with every X session.  The first step is to move this script somewhere else so it’s never run:

$ sudo mv /etc/X11/Xsession.d/70pulseaudio /root/

The second cause of “pulseaudio” being spawned is less obvious.  There is an Esound compatibility layer for PulseAudio so that applications depending on it still work, transparently.

$ ls -l /usr/bin/esd
lrwxrwxrwx 1 root root 9 2009-03-04 11:03 /usr/bin/esd -> esdcompat

However, as of Ubuntu Intrepid (8.10) there is pretty much nothing which depends solely on Esound, but it still gets spawned when GNOME starts.  This causes a PulseAudio session to be spawned for the current user if one can’t be found.  The simple but ugly fix is to move this link to somewhere else:

$ sudo mv /usr/bin/esd /usr/bin/esd.bak

Set up a system-wide PulseAudio instance

To get PulseAudio to actually start on boot, you need to set a variable to tell the init script you want this to happen. Make sure you have the following line in /etc/default/pulseaudio:

PULSEAUDIO_SYSTEM_START=1

Any users that will be using the system-wide PulseAudio instance need to be members of the correct groups. This will most likely be your own user, plus whatever user MPD is running as (“mpd” by default). For each of these users, do:

$ sudo usermod -a -G pulse-access <user>
$ sudo usermod -a -G pulse <user>
$ sudo usermod -a -G pulse-rt <user>

Getting it up and running

First thing’s first, you need to tell MPD to use PulseAudio. This can be achieved by adding the following to /etc/mpd.conf:

audio_output {
       type    "pulse"
       name    "My MPD PulseAudio Output"
}

If you’re feeling lazy, the easiest thing to do right now would be reboot. Otherwise, you’ll need to kill all “pulseaudio” instances, restart the system-wide instance, and restart MPD.

$ sudo /etc/init.d/mpd stop
 * Stopping Music Player Daemon mpd                   [ OK ]
$ sudo killall -KILL pulseaudio
$ sudo /etc/init.d/pulseaudio restart
 * Stopping PulseAudio Daemon                         [ OK ]
 * Starting PulseAudio Daemon                         [ OK ]
$ sudo /etc/init.d/mpd start
 * Starting Music Player Daemon mpd                   [ OK ]

Finally, log out and log back in again to allow your per-session pulseaudio instance to die and for your new group memberships to take effect.

Caveats

  • You get “real-time” processing without any extra effort; by default the system-wide instance will run with priority -11.
  • Some apps are not PulseAudio-aware, but they can usually use an ALSA output; this guide shows you how to redirect ALSA through PulseAudio if you have any problems with the default setup.
  • Updates may undo the moving-a-file type of changes.

“Universities push for higher fees”

My comment on a recent BBC News article “Universities push for higher fees”:

I’m a university student from a low-income background, and having started my course just after the last raise in fees took effect, I knew from the beginning that I’d be finishing with £32k of debt (including maintenance loan).  While expensive, it’s a risk I was willing to take, since it’s the best way to equip myself for the field I enjoy.  If this number were to be more in the region of £85k, I think a lot of people would shy away from taking on such a staggering debt.

The government needs to realise that if they allow such increases, and also increase student loans to follow suit, then they will be footing the bill for allowing the fees to be raised (and therefore passing it on to the taxpayers).  The vital safety net for most students is that student loans are written off 25 years after finishing/leaving the course, and since the university already has the money, the gap has to be filled from somewhere.  This alone explains the observations leading to “Two thirds believed that fees had not deterred applications from students from poorer families”.  If the government wants to subsidise the universities, then they should propose an increase in per-student subsidies as an alternative, presenting the situation as it really is.

Any attempt to raise or un-cap fees that isn’t backed completely by student loans will be disasterous.  This would change the university admissions process to be less “those who are most able” and more “those who are most able to pay”.  For a government that campaigned on equal availability of higher education, this would be a step backwards.  In a country with a shrinking manufacturing base, intelligent well-educated individuals are a vital resource for staying competitive in a global market.

As it stands, I’ve not heard of universities being severely underfunded, and where they claim to be it can usually be attributed to mismanagement of funds.  If they could survive when we were paying £1150, why can’t they survive when we’re paying £3150?  It seems to me this may be a case of “they did it once, maybe they’ll do it again” on the part of universities, hopeful that the government will grant them more revenue without having to show anything for it.