Off-On Fourier Series

I have been fascinated lately with the concept of frequency spectrum and the idea that all periodic signals can be approximated by an infinite sum of sinusoidal functions. There are many introductory videos on this subject, usually titled as introductions to the Fourier transform.

As far as the actual math involved, this YouTube* video was very helpful:
Compute Fourier Series Representation of a Function

I don’t actually use the YouTube Website directly because of the massive amounts of proprietary JavaScript involved, but instead use youtube-dl to download the video.)

He converts an off-on type of function to a fourier series. After the integration, we get this:

I translated that into some plots in Racket, to give the visual idea. Say we only add in a single sinusoid:

Then, another:

And a few more:

And a lot more:

And finally, hundreds of them:

It cannot quite perfectly represent the function, because the Fourier series adds an extra point in between the switch from off to on (and back), whereas the original just jumps from 0 to 1 (and back).

Here is the Racket code for those interested (I did not bother to optimize):

#lang racket

(require plot)

(define (pulse x l)
  (letrec ([pulse_ 
            (lambda (acc n)
              (if (> n l) acc
                  (pulse_
                   (+ acc
                      (/ (* 2
                            (sin (* (+ (* 2 n) 1) pi x)))
                         (* (+ (* 2 n) 1) pi)))
                      (+ n 1))))])
    (pulse_ 0.5 0)))
        
(define (pulseplot l)
  (plot
   (function (lambda (x) (pulse x l)) -1 3)))

More Emacs Calculator Functionality

The first video demonstrates algebraic formulas and live evaluation in Emacs Calculator:

The second video covers two subjects: (1) mapping functions over vectors, and (2) using emacs to display algebraic formulas as math LaTeX (to paste into a WordPress post, for example). Please forgive the improper pronunciation of “LaTeX”, which I remembered afterwards.

Emacs Calc: Angle Between Vectors

In my geometry studies, I learned that one can get the angle between two vectors with this formula:

cos \theta = \frac{V_1 \cdot V_2}{| V_1 | | V_2 |}

I.e., the cosine of the angle equals the dot product of the two vectors over the product of their magnitudes.

Here we get about 1.05 radians or about 60.26 degrees. A cool thing about this formula is it works for vectors of any (matching) dimension, i.e., 3-D coordinates, 4-D coordinates, etc.

This is definitely doable in Emacs Calc, since we have a dot product function, called inner-product (press ‘x inner product’), But doing the angle formula involves a lot of steps, with either stack rotation or storing the vectors in variables. So I wanted to get the angle formula stored as a calc formula. Unfortunately, inner-product itself is only an interactive function, so this was problematic. However, inner-product actual calls another function, inner. So, this formula is possible:

arccos(inner(mul, add, v1, v2) / (abs(v1) abs(v2)))

How do you store this formula in Emacs? I could walk you through the steps described in section 18.4 of the Emacs Calc info manual, but the end result is that this code is stored in your ~/.emacs.d/calc.el:

(put 'calc-define 'calc-vectorsangle '(progn
 (defun calc-vectorsangle nil (interactive) (calc-wrapper (calc-enter-result 2 "vect" (cons (quote calcFunc-vectorsangle) (calc-top-list-n 2)))))
 (put 'calc-vectorsangle 'calc-user-defn 't)
 (defun calcFunc-vectorsangle (v1 v2) (math-normalize (list (quote
  calcFunc-arccos) (list (quote /) (list (quote calcFunc-inner) (quote
  (var mul var-mul)) (quote (var add var-add)) v1 v2) (list (quote *)
  (list (quote calcFunc-abs) v1) (list (quote calcFunc-abs) v2))))))
 (put 'calcFunc-vectorsangle 'calc-user-defn '(calcFunc-arccos (/
  (calcFunc-inner (var mul var-mul) (var add var-add) (var v1 var-v1)
  (var v2 var-v2)) (* (calcFunc-abs (var v1 var-v1)) (calcFunc-abs (var
  v2 var-v2))))))
 (define-key calc-mode-map "zA" 'calc-vectorsangle)
))

Then when you start calc, you can put two vectors on the stack, and enter command ‘x vectorsangle’ or ‘z A’ for short:

This will work for vectors with as many more coordinates as you want, so long as there are the same number in each vector.

Trigonometry Problem without Trigonometry

Here is a classic trigonometry problem:

With the satellite dish pointed up 13 degrees above the ground, how far up will the Line of Sight (LOS) be after passing over 100 meters of ground? (To save a few sentences in our post, we will ignore the fact that the satellite dish will usually start a few meters above the ground.)

This is simple using any calculator with the trigonometry function tangent:

tan(ϕ) = opp/adj, so height = 100 * tan 13° (after 13° is converted to radians).

If you didn’t want to use a trigonometric function, however, what could you do? Another approach is complex numbers, and it is pretty simple. You simply need to rotate ϕ degrees up the unit circle (a basic operation with complex numbers), get the real and imaginary parts of that complex number, and use that proportion to figure out the opposite side of your problem triangle.

So, after raising e^i by 13 degrees (converted to radians) multiply 100 x (imag Z / real Z). In programming code, it looks like this:

#lang racket

(define tau (* 2 pi))

(define rfact (/ tau 360))

(define (rise gnd deg)
  (let* ([rad (* deg rfact)]
         [Z (exp (* 0+1i rad))])
    (/ (* gnd (imag-part Z)) (real-part Z))))

> (rise 100 13)
23.08681911255631

It gives geometrically sane results also if you use negative degrees or negative distances:

> (rise 100 -13)
-23.08681911255631
> (rise -100 -13)
23.08681911255631
> (rise -100 13)
-23.08681911255631

What if you don’t have or want to use the exp function (to raise e to some value). You instead start with an approximation of e^i, which happens to be

0.5403023058681398+0.8414709848078965i

and then just raise that to ϕ.

Now, why would you want to use the complex number approach rather than the trig function? Well, to be honest I couldn’t think of a really compelling reason off the top of my head. An easy one would be if you were already using complex numbers for other reasons. Another would be if you wanted to use purely algebraic operations in your programming, say, on a computer board that did not have trigonometric functions built in. I suspect that the complex number approach is ultimately simpler and more efficient on the computational level, but since trigonometric functions are usually approximated with tables and with an algebraic exponential function, I couldn’t really say for sure off the top of my head.

In any case, it seems cool that complex numbers allow you to do an angle and distance trigonometry problem without trigonometry.

Rotary Harmonograph with Dampening

To get some more artistic variety in the simulated rotary harmonograph output, we introduce a dampening, i.e., causing the pen and table to run down as though from friction. Also, we can nudge our simple ratio slightly, to add a small element of discord or imperfection.

Here is the adjusted function:

(define (rot ang/tunit t phase dampfact)
  (* (make-rectangular (expt dampfact t) 0)
   (expt ei
         (+ phase (* ang/tunit t)))))

With very fine control of the ratios, dampening factor, and number of samples, we can produce a variety of effects. (I’m guessing this would be much more difficult with a physical harmonograph.)