Hi, Nick,
No whacks intended! It was an easy catch because I was mulling over
similar problems with my code. My own second pass at a vmode
implementation for Calc is below, now with support for negative values
and bimodal data. It takes a different route and is a bit shorter, but
doesn't handle all the cases your code does (I guess; I don't grok it
all).
Yours,
Christian
(defmath vmode (vec)
"Return the mode(s), i.e. most frequent value(s), of a vector
of integers VEC."
(let ((results (vec)) ; hold results
(index 1)
offset maxfreq)
(setq offset (- 1 (vmin vec))
vec (+ offset vec) ; bump all ints positive
freq (histogram vec (1+ (vmax vec)))
offset (1+ offset) ; histogram added `0' slot
maxfreq (vmax freq))
;; Collect indexes (less offset) of all max freqs
(while (> (setq index (find freq maxfreq index)) 0)
(setq results (vconcat results index)
index (1+ index)))
(setq results (- results offset)) ; get neg ints back
;; Return results as vector or number
(if (> (vlen results) 1)
results
(head results))))
On 9/20/11 4:59 PM, Nick Dokos wrote:
Christian Moe<m...@christianmoe.com> wrote:
I think your vmode() needs to subtract one from the result. The mode
in the "systolic" column of Jude's dataset should be 124 (f=12), not
125 (f=2).
Yes, this is an off-by-one error: in vfreqs, I should cons prev onto
freqs, not (nth 0 vec). In addition to this and the multimodal problem
that both you and Lawrence Mitchell pointed out, there is another
off-by-one error when vfreqs gets to the end of the list.
All in all, a disaster: can a posting be deleted? or at least marked
with a big, red X so that it won't mislead in the future? I'll try to
post a corrected version later on.
OTOH, my main interest in this was the hooking up of a user function
onto calc and the example, though deeply flawed, does illustrate that.
Thanks to both Christian and Lawrence for the whacks in the head
(although now I have a headache...)
Nick