;;;; Programmer: Kevin M. Rosenberg
;;;; Date Started: Nov 2002
;;;;
-;;;; $Id: math.lisp,v 1.2 2003/04/28 16:07:42 kevin Exp $
+;;;; $Id$
;;;;
;;;; This file, part of KMRCL, is Copyright (c) 2002 by Kevin M. Rosenberg
;;;;
;;;; *************************************************************************
-(in-package :kmrcl)
+(in-package #:kmrcl)
(defun deriv (f dx)
#'(lambda (x)
(funcall (deriv #'sin 1d-8) x))
;;; (sin^ pi)
+
+(defmacro ensure-integer (obj)
+ "Ensure object is an integer. If it is a string, then parse it"
+ `(if (stringp ,obj)
+ (parse-integer ,obj)
+ ,obj))
+
+(defun histogram (v n-bins &key min max)
+ (declare (fixnum n-bins))
+ (when (listp v)
+ (setq v (coerce v 'vector)))
+ (when (zerop (length v))
+ (return-from histogram (values nil nil nil)) )
+ (let ((n (length v))
+ (bins (make-array n-bins :element-type 'integer :initial-element 0))
+ found-min found-max)
+ (declare (fixnum n))
+ (unless (and min max)
+ (setq found-min (aref v 0)
+ found-max (aref v 0))
+ (loop for i fixnum from 1 to (1- n)
+ do
+ (let ((x (aref v i)))
+ (cond
+ ((> x found-max)
+ (setq found-max x))
+ ((< x found-min)
+ (setq found-min x)))))
+ (unless min
+ (setq min found-min))
+ (unless max
+ (setq max found-max)))
+ (let ((width (/ (- max min) n-bins)))
+ (setq width (+ width (* double-float-epsilon width)))
+ (dotimes (i n)
+ (let ((bin (nth-value 0 (truncate (- (aref v i) min) width))))
+ (declare (fixnum bin))
+ (when (and (not (minusp bin))
+ (< bin n-bins))
+ (incf (aref bins bin))))))
+ (values bins min max)))
+
+
+(defun fixnum-width ()
+ (nth-value 0 (truncate (+ (/ (log (1+ most-positive-fixnum)) (log 2)) .5))))