[racket] Advice on using math/array and math/matrix to rewrite MATLAB code

From: Jens Axel Søgaard (jensaxel at soegaard.net)
Date: Sat May 3 10:09:23 EDT 2014

2014-05-03 8:43 GMT+02:00 Daniel Prager <daniel.a.prager at gmail.com>:
> I'm having a go at converting a pitch detection algorithm from MATLAB to
> Typed Racket, and which I'll Open Source if I can get it working, and am
> after a few pointers, since I'm new to TR and am finding it slow going.
>
> Examples of the kind of code I'm writing in my fledlging attempts:
>
> #lang typed/racket
>
> (define: (log2 [x : Real]) : Real
>   (define result (/ (log x) (log 2)))
>   (if (real? result)
>       result
>       0.0))

My strategy is write the write the function in normal Racket first:

  (define (log2 x)
      (/ (log x) (log 2)))

Then to add the type:

  (: log2 : Real -> Real)
  (define (log2 x)
      (/ (log x) (log 2)))

In this case I get a type error, the result is not a Real but a Number.
If x is negative, then (log x) is a complex number. I therefore need
to insert a an explicit check that x is positive:

(: log2 : Real -> Real)
(define (log2 x)
    (cond [(positive? x) (/ (log x) (log 2))]
              [else             (error 'log2 "positive number expected")]))

This version type checks.

> (define: (build-step-vector [min : Real] [step : Real] [max : Real]) :
>   (Vectorof Real)
>   (for/vector: : (Vectorof Real)
>       #:length (ceiling (inexact->exact (/ (- max min) step)))
>       ([i (in-naturals)])
>     (+ min (* i step))))

Here I tried this version:

(: step-vector : Real Real Real -> (Vectorof Real))
(define (step-vector min max step)
  (for/vector #:length (exact-ceiling (/ (- max min) step))
    ([x (in-range min max step)])
    x))

This gave an error, since TR could only infer that the result was a
(Vectorof Any).
Then I changed it to:

(: step-vector : Real Real Real -> (Vectorof Real))
(define (step-vector min max step)
  (for/vector: : (Vectorof Real) #:length (exact-ceiling (/ (- max min) step))
    ([x (in-range min max step)])
    x))

> Beyond that:
>
> Can anyone point me to examples of any code before/after converted from
> MATLAB (or Octave) to TR?

I haven't any experience with either (except reading parts of the
documentation).
Do you have any particular examples in mind?

> What's a good scalar type to work with for floating point to start with?

Flonum ?

> Which non-scalar type(s) should I favor: vectors, arrays or matrices?

Matrices are just two-dimensional arrays. Therefore if there is a matrix
operation missing, mostly likely you can find it in the array section
of the documentation.

If you stick with matrices, you can view vectors as nx1 matrices.
This allows you to use the matrix operations on vectors.

Depending on the operations you need, I'd try out matrices.

> Any general tips to develop facility for this kind of stuff? I feel like I
> need to go "back to basics", but there seems to be a dearth of examples and
> tutorials. on math/... beyond the reference materials.

True.

/Jens Axel

Posted on the users mailing list.