The Hidden Variable Approach?
Vector 13:2, page 27
Transcribed from the printed issue; not yet reviewed. Read it in the PDF of the issue, page 27
In J-ottings 8 Norman Thomson provided a different view of the uniform partition function. The approach scales up a division of (0,1) to the width of the given interval and moves it to the correct starting point. Writing Norman’s function a little differently, but assuming the same syntax "n sample a,b" for a partition of the interval (a,b) into n sub-divisions:
start_point_a =. {.@] NB. "a" in n sample a,b
indices =. i.@ >: NB. 0 1 2 3 4 5 ... n
sample_01 =. %~ indices NB. 0, 1/n, 2/n, 3/n, ..., 1
n_width =. -/ NB. a - b
scaled_sample =.( * sample_01)~ n_width NB. (a-b)* (0, 1/n, 2/n, ..., 1)
sample =. start_point_a - scaled_sample NB. a + (b-a)*(0, 1/n, 2/n, ..., 1)
The fixed form of sample is {.@] - ((* (%~ i.@>:))~ -/) and unfortunately has two more characters than Norman’s function, but it has only one reference to ]. On my machine it ran marginally faster for small samples, and marginally slower for larger samples.
It is a novel and an exhilarating experience to write a function like this, but note what has to be remembered:
- functions
start_point_aandscaled_samplemust have the same dyadic syntax assampleto fit the final fork indicesis monadic, BECAUSE it will be used as second verb in the monadic hooksample_01sample_01is monadic because it is used in the hookscaled_samplescaled_sampleis a dyadic hook andn_widthwill be applied monadically.
I think the point I was trying to make was that any pupil in junior high school will be able to see how a + ((b-a)%n )* indices or a + (b-a)* indices%n works. They might have more trouble with the hidden variable approach or they may enjoy it, but their teachers will probably have a pink fit just thinking about it.
The "go-get-the-variable" approach is bound to have repetitions, because with tacit definition there is nowhere to store data. Incidentally, if one notes that the sample points are given by ((1 - sample_01) * a) + sample_01 * b, then we have a couple more symbols in (+/ .* (-. ,: +)@(%~ i.@>:))~ and 30% slower execution time, but no square brackets at all. The original {.@] + (({:@] - {.@] )% [ ) */ (i.@>:@[ ) with the most symbols and [ and ] references is slowest of all for small samples, but faster than all of them on my machine when n is large.
Execution times:
n T R S M
113 0.0297 0.0307 0.0374 0.0346
913 0.0758 0.0692 0.0697 0.0984
3917 0.256 0.2224 0.2126 0.3405
9919 0.6124 0.5223 0.4455 0.8327
where: