Issue #6

 2006-12-03

A taste of Squeak for Signal Processing folks

 

 

I’m a member of the BuenaSeñal group. It is a Spanish speaking group where we talk about signal processing techniques, and audio applications. I’m trying to convince the folks there that Squeak is a great tool for signal processing.

 

Hernán Ordiales said he was looking for alternatives to Matlab, and heard about Python (if you can read Spanish, he describes his first experience with Python here).

 

Squeak is an open and free implementation of Smalltalk. It’s my choice whenever I can use it.

 

As a short exercise to learn a bit about Python, Hernán did plots of magnitude and phase of the FFT of an array consisting of ten 1’s and ninety 0’s. His Python code is below. 

 

So, I thought he would enjoy a Squeak version (Hernán, I hope you do!). My Squeak code after his. Please note that this is neither a tutorial nor a real introduction to Smalltalk. It is just a small code example, to take a look if you have ten minutes.

 

Python version

 

#!/usr/bin/python

# -*- coding: UTF-8 -*-

 

from pylab import *

 

L = 10

x = ones( L )

 

# Figura 3: N = 100

N = 100

X = fft( x, N )

figure(3)

subplot(311)

title('N = 100')

horiz = arange(0,L,1)

stem( horiz, x )

subplot(312)

horiz = arange(0,N,1)

stem( horiz, abs(X) )

subplot(313)

stem( horiz, angle(X) )

savefig( 'figura3.png' )

 

show()

 

First Squeak version

 

Display fillGray.

 

pi := Float pi.

fft := FFT new: 128.

fft realData atAll: (1 to: 10) put: 1.

fft transformForward: true.

abs := fft realData with: fft imagData collect: [ :r :i | (r@i) r].

fft plot: abs in: (20@20 extent: 880@320).

angle := fft realData with: fft imagData collect: [ :r :i | (r@i) theta].

angle := angle collect: [ :a | a negated + pi \\ (2 * pi ) - pi].

fft plot: angle in: (20@380 extent: 880@320).

 

Display writeBMPfileNamed: 'image4.bmp'.

 

Below you can see the generated plot.

The code is short enough to comment each line. The first thing to know is that in Smalltalk all the programming is done by sending messages to objects. The syntax is a bit different from most languages, but it is easy to read.

 

The line Display fillGray. erases the display.

 

The line pi := Float pi. assigns to variable pi the result of sending message #pi to object Float. Therefore variable pi contains the floating point number for Pi. Asignment is done with := . We usually prefix the name of messages with #.

 

The line fft := FFT new: 128. assigns a new FFT object of size 128 to variable fft. FFT and Float are existing objects. They are classes (like classes in any object oriented language). In Smalltalk, classes are regular objects and you can send them messages, like #pi or #new:. In Squeak, FFT is implemented for sizes being integer powers of two.

 

The line fft realData atAll: (1 to: 10) put: 1. puts the value 1 at the first ten positions of the real input to the FFT. This is done by first asking the fft for its realData, and sending to the array the message #atAll:put:. The arguments to this call are the interval [1..10] and 1.

 

The line fft transformForward: true. does the transform, in “forward” direction, i.e. from time domain to frequency domain.

 

The line abs := fft realData with: fft imagData collect: [ :r :i | (r@i) r]. assigns to variable abs the magnitudes of the result.

 

The line fft plot: abs in: (20@20 extent: 880@320). plots variable abs.

 

The line angle := fft realData with: fft imagData collect: [ :r :i | (r@i) theta]. assigns to variable angle the angles of the result.

 

The line angle := angle collect: [ :a | a negated + pi \\ (2 * pi ) - pi]. adjust for a difference between Squeak and Python, to get the same graph as Hernán. In Python the angles for complex numbers are in [-pi .. pi] and in Squeak in [0 .. 2pi].

 

The line fft plot: angle in: (20@380 extent: 880@320). plots variable angle.

 

The line Display writeBMPfileNamed: 'image4.bmp' saves the graphs in a file.

 

Second Squeak version

 

In the first version, we had to obtain the magnitudes and phase angles of the results “by hand”. But in Smalltalk it is very easy to add new methods to any class. Next time we want to do something alike, we won’t have to write all over again. So, let’s add these 5 methods to class FFT:

 

magnitudes

          ^realData with: imagData collect: [ :r :i | (r@i) r]

 

angles

          ^realData with: imagData collect: [ :r :i | (r@i) theta]

 

angles2

          | pi |

          pi := Float pi.

          ^self angles collect: [ :a | a negated + pi \\ (2 * pi ) - pi]

 

plotMagnitudesIn: aRectangle

          self plot: self magnitudes in: aRectangle

 

plotAnglesIn: aRectangle

          self plot: self angles2 in: aRectangle

 

The first line of a method is it’s name (the message) and is aligned to the left. The rest of the code is indented to the right. | pi | is the way to declare a local variable. ^ is the way to return an object as a result of the message send. I hope the purpose of the methods is obvious, as they repeat code from the first version. Now the script is:

 

Display fillGray.

fft := FFT new: 128.

fft realData atAll: (1 to: 10) put: 1.

fft transformForward: true.

fft plotMagnitudesIn: (20@20 extent: 880@320).

fft plotAnglesIn: (20@380 extent: 880@320).

Display writeBMPfileNamed: 'image4.bmp'

 

A bit shorter, isn’t it? This is the generated graph:

 

 

 

BuenaSeñal folks, I hope you liked this tiny example of Squeak.

 

 

Juan Vuletich