## Histograms in APL/Scheme

Eric gave a talk today about the Connection Machines and CM Lisp. One of the examples was of a way to compute the histogram of a set of numbers:

The basic idea here is that given a Xector X (e.g. -- [5 5 2 5 3 2]), you can compute a Xector of the counts of each using the above expression.

I began to think that this looks a lot of like an APL function/operator combination, so I went to my APLX scrapbook to find something for a histogram. I found one, but I was not quite happy with it. It works well enough, but it does not handle arrays that don't have a one in them. Instead, with a little twist, I managed to make it work for any given range:

Of course, why stop there when we can use a few more characters and get the actual visual representation of things all laid out for us:

This actually does a bit more than the CM Lisp expression above does. The output of this for an array X where X=5 5 2 5 3 2 would be something more like this:

And of course, none of this would be complete without an example in Scheme of doing the same thing.

Without a doubt, the β operator in CM Lisp is a very cool thing. It's almost like a combination of APL's reduce and indexing operators combined into one. We simulate this sort of behavior using a matrix in the APL version, and in the Scheme version, I manually do the tracking with the vector.

Actually, I think both the APL and Scheme versions are pleasantly concise. If I did not care about keeping the actual indexes in the Scheme version, then it would be even more concise.

(β+ X ⍺1)

The basic idea here is that given a Xector X (e.g. -- [5 5 2 5 3 2]), you can compute a Xector of the counts of each using the above expression.

I began to think that this looks a lot of like an APL function/operator combination, so I went to my APLX scrapbook to find something for a histogram. I found one, but I was not quite happy with it. It works well enough, but it does not handle arrays that don't have a one in them. Instead, with a little twist, I managed to make it work for any given range:

+/((¯1+⌊/X)↓⍳1+⌈/X)∘.=X ⍝ Another Possibility +/((⌊/X)+⍳1+(⌈/X)-⌊/X)∘.=X

Of course, why stop there when we can use a few more characters and get the actual visual representation of things all laid out for us:

' ⎕'[⎕IO+(⌽⍳⌈/A)∘.≤A←+/((⌊/X)+⍳1+(⌈/X)-⌊/X)∘.=X]

This actually does a bit more than the CM Lisp expression above does. The output of this for an array X where X=5 5 2 5 3 2 would be something more like this:

⎕ ⎕ ⎕ ⎕⎕ ⎕

And of course, none of this would be complete without an example in Scheme of doing the same thing.

(define (histogram x) (let* ([sm (apply min x)] [rng (1+ (- (apply max x) sm))] [v (make-vector rng 0)] [inc (lambda (n) (vector-set! v n (1+ (vector-ref v n))))]) (for-each inc x) (map list (map (lambda (x) (+ x sm)) (iota rng)) (vector->list v))))

Without a doubt, the β operator in CM Lisp is a very cool thing. It's almost like a combination of APL's reduce and indexing operators combined into one. We simulate this sort of behavior using a matrix in the APL version, and in the Scheme version, I manually do the tracking with the vector.

Actually, I think both the APL and Scheme versions are pleasantly concise. If I did not care about keeping the actual indexes in the Scheme version, then it would be even more concise.