Defining AVERAGING clause

Russ Tyndall russ at acceleration.net
Tue Mar 13 15:08:09 UTC 2018


Here is an existing "sampling" clause to pull a random sample from a 
larger data set.  The long and short is just use a finally clause, as 
you would when writing a normal iterate loop.

(iterate:defmacro-clause (sampling expr &optional into var size size)
   "resevoir sample the input"
   (let ((sample (or var iterate::*result-var*)))
     (alexandria:with-unique-names (i sample-size sigil buffer row)
       `(progn
         (with ,sample)
         (with ,sample-size = (or ,size 100))
         (with ,buffer = (make-array ,sample-size :initial-element ',sigil))
         (with ,i = 0)
         (if (< ,i ,sample-size)
             (setf (aref ,buffer ,i) ,expr)
             (let ((r (random ,i)))
               (when (< r ,sample-size)
                 (setf (aref ,buffer r) ,expr))))
         (incf ,i)
         (finally
          ;; convert our sample to a list, but only if we actually took 
the sample
          (when (plusp ,i)
            (setf ,sample
                  (iter (for ,row in-vector ,buffer)
                    (until (eq ,row ',sigil))
                    (collect ,row)))))))))

Cheers,
Russ Tyndall
Acceleration.net
On 03/13/2018 10:49 AM, Robert Goldman wrote:
>
> I was going to define an |AVERAGING| collector clause for iterate, but 
> I'm not sure how to do it. The obvious thing, it seemed to me, would 
> be to sum the values as I go along, and count them, and then divide 
> the sum by the count when leaving the loop.
>
> But the examples for |DEFMACRO-CLAUSE| in the manual do all of their 
> work while iterating, and there doesn't seem to be an "at-end" hook. 
> Is the kind of thing I would like feasible, and if so, how is it to be 
> done?
>
> thanks!
> r
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.common-lisp.net/pipermail/iterate-devel/attachments/20180313/1c6cdfce/attachment.html>


More information about the iterate-devel mailing list