Thursday, September 04, 2008

Course web pages, LaTeX, and Mercurial — Oh, my!

I have been assigned to TA yet another different course for the Autumn 2008 quarter. That was a bummer for me because I have been taking instruction way too seriously, and it has been taking up way too much of my time. However, I've been pretty happy with the results. I've been getting flattering praise and very helpful feedback. More importantly for this post, I've been producing lots of revision-controlled content that can be used for reference or as examples.

The four course web pages that I've produced so far...I've tried to generate lots of reference material all with LaTeX, and I've tried to put the sites together so that everything can be build via standard Makefiles. I've put all of the source code (minus the exams/quizzes) at my public Mercurial repository home:In my latest adventure, ECE 209, I'm going to give my students extra credit if they use TeX for any assignments they hand in. So I've put getting-started information at those web pages, and they can use the Mercurial repositories for more working examples.

I'm really a lot more proud of this work than I thought I'd be. I'm actually looking forward to the new ECE 209 class. It's the youngest group of college students I've taught since a long time ago, and I think it will be interesting. Yesterday I went through and got the lab in order. I put up instructive signs about how to use oscilloscope probes and pin-outs of commonly-used ICs. I numbered all of the tables. I added notes to the function generators telling them how to set them for high impedance output termination. Earlier I went through and repaired all of the phase-shifter circuits (out of 16 circuits, only about 4 were working, but the other 12 could be easily repaired with a little solder and/or a new op-amp IC) and added a little instructive page on how they work. Now all that's left is the actual experience that will make me even more jaded and realize that all of that work was for nothing. :)

Meanwhile though... Lots of free LaTeX examples and circuit references. Yay!

iTerm AppleScript crashing fix

Lately, my officemate and I noticed that iTerm build 0.9.5.0902 crashes whenever AppleScript tries to talk to it. I was excited about some of the full screen fixes, but I couldn't do without my "Open iTerm Here" context menu item, and so I had to come up with a fix.

In my old scripts, I was doing things like this:
tell application "iTerm"
activate
set theTerm to make new terminal
tell theTerm
set theSession to make new session at the end of sessions
tell theSession to
exec command "/bin/bash -login"
write text "ls"
end tell
end tell
end tell
It appears like it's the make new session that's causing the problem. So I changed the set theSession... and tell theSession... lines to use a launch instead. The result:
tell application "iTerm"
activate
set theTerm to make new terminal
tell theTerm
launch session "Default Session"
tell the last session
exec command "/bin/bash -login"
write text "ls"
end tell
end tell
end tell
Not only does that not crash for me anymore, but it seems to be a bit faster (my imagination?).

Tuesday, August 19, 2008

Building MATLAB images from Makefiles

Recently I beefed up my LaTeX Makefiles to make image generation more automatic. These implicit rules have worked very well for me (note that the indentation is done with TABS — that's important).
%.pdf : %.eps
epstopdf $*.eps

%.eps : %.m
matlab -nosplash -nodesktop -r "$*;quit"

%.eps : %.png
convert -density $(RESOLUTION) $*.png $*.eps

%.eps : %.jpg
convert -density $(RESOLUTION) $*.jpg $*.eps

%.eps : %.dvi
dvips $* -D $(RESOLUTION) -E -o $*.eps

%.dvi : %.tex
latex -interaction=nonstopmode $*.tex
rm -f $*.log
rm -f $*.aux
That if, if I need a file called FILENAME.eps or FILENAME.pdf, the Makefile will look for FILENAME.m, FILENAME.png, FILENAME.jpg, or FILENAME.tex. Depending on which one it finds, it will run the appropriate command to generate the image I need. Note that I define RESOLUTION=1500 in the top of my Makefile.

I want to point out the MATLAB build line:
matlab -nosplash -nodesktop -r "$*;quit"
That handy line starts up as little of MATLAB as possible and runs a script that contains something like:
% First, generate a figure somehow

% Next, setup the figure's print proportions
set( gcf, 'PaperType', 'usletter', ...
'PaperOrientation', 'portrait', ...
'PaperPosition', [0.0 3.5 11 3.5] );

% Finally, save the figure as a (color) EPS
saveas( gcf, 'FILENAME.eps', 'epsc2' );
After the script finishes, MATLAB exits. It won't get started on any subsequent makes so long as the script file doesn't change or the image isn't deleted.

Getting back to the more general case, up high in my Makefile, I have something like
RESOLUTION=1500
BASETEXIMAGES=$(shell perl -ne \
'/\\includegraphics\s*(?:\[.*?\]|)\s*{\s*(.*?)\s*}/ \
&& do { print "$$1 " \
if (-e "$${1}.tex" || \
-e "$${1}.png" || \
-e "$${1}.jpg" || \
-e "$${1}.m"); };' *.tex)
TEXIMAGES=$(addsuffix .eps,$(BASETEXIMAGES))
and a little later I make $(TEXIMAGES) a dependency for my document (or something equivalent to that).

Those lines have saved me a lot of time, and I'm pretty happy about them.

Wednesday, August 13, 2008

"Don't Be Upset" by Jeffrey and Jack Lewis

Great lyrics and a fun little song...
i took my darling out to the aquarium
sea creatures stared at us and we stared back at them
my baby freaked when she peeked at that 8-legged blob with a beak
she was too scared to speak
i said don't be upset it's only an octopus
don't bother it and i'm sure it won't bother us
please don't be upset my darling, please don't get upset
my baby came riding to meet me one time
on the crowed last car of the downtown-bound 9
she was brave but she caved
when the train was delayed
it was just the last straw in her hard busy day
i said don't get upset 'cuz it's not a catastrophe
nothing will happen and soon you'll be back with me
please don't be upset my darling , please don't be upset
my gal's got a headhache, her ankle is hurting too
boots she bought gave her a rash & her winsdom tooth
is coming in and it's damp out and she's having cramps and she's so mad at me cuz i didn't shave
i said don't be upset i know you're feeling sensitive
i'll try to be kinder and be more attentive
please don't be upset my darling please don't get upset
darling i said, i'm gonna be 27 soon
i've only got rejection letters and a sense of impending doom
i think it's too late for me
all the comic companies hate me
and i try but it's always the same
i guess my art is just lame and it's strange but still somehow i'm
always not suiting their needs at this time
and she said ........don't be upset,
you know that you're wonderful
just keep on trying ...(actually what she really said was)
all you ever wanna talk about is your self and your comic books and your album and your tour
and everytime i see your friends they just ask me where you are again and it hurts
it makes me feel like dirt
i'm just gonna write where you are on my shirt
and i said don't be upset, don't be in a bad mood
let's just go to a show and hang out and feel good
come on please don't be upset my darling, please don't be upset, i'll do anything baby, just don't be upset

Monday, July 28, 2008

Adding section or subsection to every reference (but not label)

In the form topic, "Full context variable depth references to list labels?," someone wanted to force LaTeX to
  • use legal-format lists
  • reformat its references to prefix them with the full subsection number (e.g., "2.1-") when inside a subsection and section number (e.g., "2-") otherwise.
I suggested:
\usepackage{enumitem}
\newlist{legal}{enumerate}{10}
\makeatletter
\setlist[legal]{label*=\arabic*.,
ref=\csname
the\enit@prevlabel
\endcsname\arabic*.}
\newcommand\thesectionlabel{%
\ifnum\value{subsection}=0
\thesection
\else
\thesubsection
\fi}
\newcommand{\thelegal}{\thesectionlabel-}
\makeatother

\usepackage{varioref}
\labelformat{equation}%
{\thesectionlabel-\textup{(#1)}}
\labelformat{figure}{\thesectionlabel-#1}
\labelformat{table}{\thesectionlabel-#1}
I've wrapped lines (by inserting VERY important % characters in special places to make the snippet viewable in this thin blog. As you can see in the original thread, my suggestion looked shorter because the lines were unwrapped.

It seems to work well and is one of those solutions that TeXnicians would probably do on their own without a second thought and would never document, but it's something complicated-enough that everyone else would tear their hair out searching for it.

Saturday, June 28, 2008

pedagogical moment: LaTeX, TeX, environments, and csname

On the MiKTeX mailing list, a thread descended into a flame that someone bracketed with \flameon and \flameoff, which is a sort of Fantastic Four version of a LaTeX environment. The thread involved the differences between TeX, Plain TeX, and LaTeX, and so I took the opportunity to point a few things out. I received several positive responses, and so I decided to reproduce my post here.
\pedagogical

There's a TeX vs. LaTeX teachable moment here . . .

> > \flameon
...
> > \flameoff


     As an example, if you're using LaTeX, the proper code for a flame environment is:
\begin{flame}
\end{flame}
However, the \begin and \end macros do nothing more than call:
\flame
\endflame
and so bracketing an environment in these macros is (in principle) equivalent to using the \begin and \end environments.

     Further, a naive implementation of \begin and \end is:
\newcommand\begin[1]{\csname #1\endcsname}
\newcommand\end[1]{\csname end#1\endcsname}
which is equivalent to the "raw" TeX (which may also be used in LaTeX):
\def\begin#1{\csname #1\endcsname}
\def\end#1{\csname end#1\endcsname}
In other words, \newcommand and \def are basically the same beast. However, \newcommand is a macro (created with \def) that checks to make sure you haven't already \newcommand'd before. SIMILARLY, the REAL \begin and \end wrappers have extra sanity checks for safety.

     Finally, that leaves
\csname BLAH\endcsname
which is equivalent to
\BLAH
Notice that it looks like an environment. So I could also do:
\begin{csname}today\end{csname}
which actually gives me the same output as \today.

\endpedagogical

     --Ted
I should also note that the source code for LaTeX is listed in the source2e.pdf documentation that comes with nearly every LaTeX distribution (it does not appear to come with MiKTeX). Execute
texdoc source2e
to see the document on your system.

Friday, June 27, 2008

Interpolating for Zero-Crossing Detection in MATLAB

Today someone who read my post on sinc interpolation in MATLAB e-mailed me to ask about how to interpolate between data points in MATLAB to do accurate zero-crossing detection. Here, I summarize my response.

Detecting zero crossings of (nearly) square waves that are sampled is difficult to do accurately because it pushes the limits of the "band-limited" signal approximation we use when sampling. That being said, if you'd like to use sinc interpolation, you should decide *HOW* close you need to be to the zero crossing. For example, your original signal might have 50 picoseconds between samples, and so without interpolation, you can detect zero crossings accurate within 50 picoseconds (ps). Maybe you need a closer result. How close do you need to be? 10ps? 5ps? 1ps? Less than that?

Figure out how close you need to be and then generate the appropriate upsampled time vector:
uptime = 0:step_size:final_time;
where step_size is your tolerance (e.g., 5 ps) and final_time is the maximum value of your sampled time vector. It is a good idea to engineer your step_size and final_time so that length(uptime)/length(old_time) is an INTEGER. It's also a good idea to make sure that all of your old_time points (except maybe your last point) exist in your uptime vector (i.e., your uptime vector just has time ADDED between old_time points).

Then you can use any interpolation mechanism you'd like. If you want to use the sinc_interp function that I wrote, do something like:
new_values = sinc_interp( old_values, old_time, uptime );
If you use sinc_interp, make sure you use the VECTORIZED version, which is MUCH faster. Actually, MATLAB provides a MUCH faster function that does NEARLY the exact same thing — the interpft command. In that case, you do
new_values = interpft( old_values, length(uptime) )
Otherwise, you might have luck using the resample command in MATLAB (it does NOT do pure sinc interpolation; it's more sophisticated, and it may not match at every data point):
new_values = resample( old_values, P, Q );
where P/Q is the INTEGER representing length(new_time)/length(old_time) (again, engineer your step_size to make this possible). ALTERNATIVELY, interp works OK too:
new_values = interp( old_values, P/Q );
Try all three and see which one works best for you.

Once you have this new interpolated vector, use some mechanism to detect zero crossings. Off the top of my head, here's the fastest way I can think of to do the zero-detection. Assume that we have
  • y (column vector of data -- e.g., new_values)
  • t (column vector of time -- e.g., uptime)
Also assume that t is already sorted. Then... (note that union sorts too)
i = union( find(y==0), find(conv(sign(y),[1 1]) == 0) );
should give you the MATLAB indexes where y crosses zero.

To test, try...
plot( t, y );
hold on;
stem( t(i), max(y)*ones(size(i)) );
hold off;
The result should be a plot of your data with spikes added at each zero crossing. That example also demonstrates how you recover the particular zero-crossing times with
t(i)
For example, when I apply this algorithm to a sin(t) waveform, t(i) gives me 0, pi, 2*pi, and 3*pi out, as expected.

Thursday, June 26, 2008

sinc interpolation in MATLAB

UPDATE: The examples given here are meant to give mathematical insight into how sinc interpolation works by using a finite-time APPROXIMATION. Sinc interpolation necessarily involves a circular convolution, which is not a finite computation in the time domain. If you actually need to do sinc interpolation, use the interpft function. It does an FFT, pads the FFT with zeros, and does an IFFT. Consequently, it is VERY FAST. Moreover, using an FFT (or DFT, in general) is the only way to use a finite computation to do a sinc interpolation (or circular convolution in general). Just make sure that the resampled time vector you use has a length that is an integer multiple of your original time vector. Also make sure that it lands on the same points as your original time vector (i.e., it should only add new points between old points).

I've also created a interpftw that does the same job as interpft but allows you to reconstruct samples from different aliasing windows. Whereas interpft pads the end of the FFT with zeros, interpftw pads both the beginning and the end. In other words, the former is a low-pass filter and the latter is a bandpass filter.
If you search Google for sinc interpolation in MATLAB, many pages will reference the sinc_interp example from John Loomis. Unfortunately, I've found few sites that recognize that the function is not meant to do general purpose sinc interpolation. That is, it makes a few assumptions about the sampling rates that may not be evident to the average user.

So, I'm giving some of my students this example:
% Ideally "resamples" x vector from s to u by sinc interpolation
function y = sinc_interp(x,s,u)
    % Interpolates x sampled sampled at "s" instants
    % Output y is sampled at "u" instants ("u" for "upsampled")


    % Find the sampling period of the undersampled signal
    T = s(2)-s(1);

    for i=1:length(u)
        y( i ) = sum( x .* sinc( (1/T)*(u(i) - s) ) );
    end

    % Make sure y is same shape as u (row->row, col->col)
    y = reshape(y, size(u));
end
Here's a vectorized (i.e., MUCH FASTER) version:
% Ideally "resamples" x vector from s to u by sinc interpolation
function y = sinc_interp(x,s,u)
    % Interpolates x sampled at "s" uniformly spaced instants
    % Output y is sampled at "u" uniformly spaced instants
    % ("s" for "sampled" and "u" for "upsampled")
    % (consequently, length(x)=length(s))


    % Find the period of the undersampled signal
    T = s(2)-s(1);

    % The entries of this matrix are each u-s permutation.
    % It will be used to generate the sinc transform that will
    % be convolved below with the input signal to do the
    % interpolation.
    %
    % (recall that u(:) will be a column vector regardless
    % of the row-ness of u. So u(:) is a row, and s(:) is a
    % column)

    sincM = repmat( u(:), 1, length(s) ) ...
           - repmat( s(:)', length(u), 1 );

    % * Sinc is the inverse Fourier transform of the boxcar in
    % the frequency domain that was used to filter out the
    % ambiguous copies of the signal generated from sampling.
    % * That sinc, which is now sampled at length(u) instants,
    % is convolved with the input signal becuse the boxcar was
    % multipled with its Fourier transform.
    % So this multiplication (which is a matrix transformation
    % of the input vector x) is an implementation of a
    % convolution.
    % (reshape is used to ensure y has same shape as upsampled u)

    y = reshape( sinc( sincM/T )*x(:) , size(u) );
end
My function sinc_interp resamples the data in the x vector. The original time vector is given by the s vector and the new time vector is given by the u vector.

Alternatively, you can try this more advanced one that lets you pick which aliasing window you want to use to reconstruct (i.e., it's an ideal bandpass filter rather than just a low-pass filter).
% Ideally "resamples" x vector from s to u by sinc interpolation
function y = sinc_interp(x,s,u,N)
    % Interpolates x sampled sampled at "s" instants
    % Output y is sampled at "u" instants ("u" for "upsampled")
    % Optionally, uses the Nth sampling window where N=0 is DC
    %     (so non-baseband signals have N = 1,2,3,...)


    if nargin < 4
        N = 0;
    end

    % Find the period of the undersampled signal
    T = s(2)-s(1);

    for i=1:length(u)
        y( i ) = ...
            sum( x .* ...
                ( (N+1)*sinc( ((N+1)/T)*(u(i) - s) ) - ...
                  N*sinc( (N/T)*(u(i) - s) ) ) );
    end
end
Here's a vectorized (i.e., MUCH FASTER) version:
% Ideally "resamples" x vector from s to u by sinc interpolation
function y = sinc_interp(x,s,u,N)
    % Interpolates x sampled sampled at "s" instants
    % Output y is sampled at "u" instants ("u" for "upsampled")
    % Optionally, uses the Nth sampling window where N=0 is DC
    % (so non-baseband signals have N = 1,2,3,...)


    if nargin < 4
        N = 0;
    end

    % Find the period of the undersampled signal
    T = s(2)-s(1);

    % When generating this matrix, remember that "s" and "u" are
    % passed as ROW vectors and "y" is expected to also be a ROW
    % vector. If everything were column vectors, we'd do.
    %
    % sincM = repmat( u, 1, length(s) ) - repmat( s', length(u), 1 );
    %
    % So that the matrix would be longer than it is wide.
    % Here, we generate the transpose of that matrix.

    sincM = repmat( u, length(s), 1 ) - repmat( s', 1, length(u) );

    % Equivalent to column vector math:
    % y = sinc( sincM'(N+1)/T )*x';

    y = x*( (N+1)*sinc( sincM*(N+1)/T ) - N*sinc( sincM*N/T ) );
end

Tuesday, June 24, 2008

Wryness in song: The Girls Don't Care

"Eef Barzelay: A Blueprint for Finding Love" by Stephen Thompson
  • Song: "The Girls Don't Care"
  • Artist: Eef Barzelay
  • CD: Lose Big
  • Genre: Pop-Rock
As leader of the now-defunct Clem Snide, Eef Barzelay took flak from critics for weaving smart-alecky wordplay and pop-culture references into his keenly observational songs. But then, with the release of 2003's Soft Spot — a concept album about the unconditional love and sacrifice inherent in marriage and parenthood — he took yet more flak for singing straightforwardly sincere love songs.

Truth be told, Barzelay's work has always mixed wryness with unmistakable warmth, and he's never gotten enough credit for both the subtlety of the former and the sincerity of the latter. Ever since Soft Spot, and starting with the title track to 2005's End of Love, he's taken to occasionally needling those for whom expressions of love run counter to a painstakingly maintained ironic distance. "You're so sophisticated / Your mind's been liberated / You're the first to notice when a movement's come and gone," he sang in "End of Love," concluding, "No one will survive the end of love."

Since then, Barzelay has released a solo acoustic record (2006's Bitter Honey), recorded Clem Snide's swan song (the still-unreleased Hungry Bird), and made Lose Big, a smart and compact collection of rock 'n' roll conversation-starters. "The Girls Don't Care" in particular functions as an ideal sequel to "End of Love," as Barzelay gently advises against hipper-than-thou posturing: "The girls don't care that you ache to be free," he sings. "The girls just want a sweet melody."

Barzelay has never been afraid to turn a pop song into a mission statement: For proof, check out Clem Snide's masterful "I Love the Unknown," which Barzelay helpfully tacks on as a bonus track to Lose Big. In "The Girls Don't Care," he lays out a bona fide blueprint for how to find love: "Don't listen to Frank Zappa / play Coltrane, Faust, or Can / Just take that twisted heart of yours and lay it in her hand."
It's a pretty song too. Have a listen at the SotD link. Song lyrics are easy to find too.

Monday, June 23, 2008

Letter to Prospective Graduate Student

Now that all of my adviser's older graduate students have graduated, I have somehow become an international ambassador (completely against my will) for the university. I've been getting e-mails from students interested in getting their PhD in the area of control here at OSU. Here's a sample response, which may or may not be helpful to some random Googler out there.
> I am interested in Fuzzy controllers in Control Systems
> and have done some paper presentation on that in under
> Grad school. I plan to take the same for my PhD studies.

It's good to hear that you're considering advanced
studies in control systems. Keep in mind that state of the
art control research is not in fuzzy control. Modern control
uses a more rigorous mathematical approach. Recent interest
in nonlinear systems has made the mathematics of real
analysis an important tool for the control researcher.

That being said, Professors Passino and Yurkovich are
experts in fuzzy control (you can see their book on the
subject). Professor Passino's current research investigates
biological and psychological systems (in particular, how to
integrate engineering ideas into those fields and use
insights from those fields to inspire engineering
solutions). Professor Yurkovich is highly active in
automobile control system research (spanning everything from
the automobile itself to the manufacturing systems that make
it). Because Professor Yurkovich's research is a little more
conventional, it tends to be more easily funded.

Additionally, there are several other strong control
faculty members here at OSU. Professor Ozguner, for
example, is a leader in coordinated control (e.g.,
integration of multiple vehicles or systems with independent
controllers). Professor Serrani is an expert in nonlinear
dynamics (e.g., control of fluid flow through an
airbreathing supersonic jet). Check out OSU's ECE webpage
for more information on the other control faculty.

> 1. How do you find the course you are pursuing. That is
> about the quality of teaching, course material and other
> facilities at the university?

I think that the courses at OSU are very strong,
especially in control and *mathematics*. Keep in mind that
OSU's math department has a strong theoretical bias, which
actually makes it ideal for engineering disciplines
surrounding communication systems, signal processing, and
control systems (a focus on algebra for the first two and
real analysis for the latter). All of these courses are
taught by experienced faculty, and I have been very happy
with the level of instruction here at OSU.

That being said, some of our facilities are older.
Additionally, primarily due to lower undergraduate
enrollment in the ECE department, *internal* funding
opportunities for graduate students have been on the
decline.

> 2. Do I need to get in touch with any Professors before
> applying for admission?

*YES*, it would be a good idea to see
what space will be available. However, many will probably
tell you to get back in touch with them after you have been
admitted to the program. Still, you should contact them to
see if they'll be available to take on new students. It is
usually best to make first contact by e-mail (though,
depending on the professor, your mileage may vary). Make your
intentions clear in your e-mail's subject (e.g., "Considering
PhD Study in Control Systems Area at OSU").

Keep in mind that many professors will favor PhD
students over MS students (which shouldn't be an issue in
your case). Additionally, the OSU ECE department has
recently "modernized" its advanced degree program. Now there
is a 4 year (nominally) "direct to PhD" program that may (or
may not) be attractive to you. You might want to consult the
"ECE Graduate Handbook" (available on the ECE webpage in the
section for graduate students) to get more details about
those programs.

In the meantime, you should definitely be pursuing
outside funding options. Having outside funding will make
you more attractive to any university and will give you more
flexibility when doing your own research.

I hope that helps. Best wishes --
Ted
I'm leaving out many details that I bitch about frequently among friends. Maybe that's because I'm optimistic that the university (and the ECE department) will "change" for the "better," or maybe that's because I don't want to be the lone miserable schmuck.