When performing Hartley Transforms, we have to make time-reversed copies of data arrays. It would be tempting to do this with a simple slicing expression that simply reverses the array.
But that is incorrect. The time reversal of an array is not the reverse of the array. Element zero -- the first element of the array -- must remain as element zero in the time reversed array.
As it happens, we can also collect non-contiguous elements of an array by using another array or a list of indexes to be extracted. So if lst is the list:
let lst = [1, 4, 6, 7]
then we can extract elements numbered 1, 4, 6, and 7 of an array by means of the slicing expression:
a.[lst]
We can make a simple one-dimensional array of integers running from zero to some upper value by means of the “ramp” operator.
let r = ramp 20
produces an array of 20 elements, starting from 0, and counting up to 19.
Hence, to produce a time-reversed array one would do something like the following:
a.[-ramp (length a)]
That is, we make a ramp array equal to the length of the array to be time-reversed, and then negate it. Since array indexing is cyclic, the negative indexes effectively address elements from the end of the array: a.[-1] is the last element of the array, a.[-2] is the second to last element, and so on.
Negating the ramp, leaves the zeroth element intact, but negates all other elements. Hence the slicing operation effectively reverses the array, but leaves element 0 in place.
One could also do something like:
a.[length a : 1]
This works because the cyclic indexing makes a.[length a] = a.[0], and because the starting index is above the ending index which produces a reversed readout. And this solution also avoids making an intermediate ramp array.
Hmm... hadn’t thought of this solution until just now, as I write this Blog entry...