r8055: now works with lispworks 4.3
[kmrcl.git] / math.lisp
1 ;;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; Base: 10 -*-
2 ;;;; *************************************************************************
3 ;;;; FILE IDENTIFICATION
4 ;;;;
5 ;;;; Name:          math.lisp
6 ;;;; Purpose:       General purpose math functions
7 ;;;; Programmer:    Kevin M. Rosenberg
8 ;;;; Date Started:  Nov 2002
9 ;;;;
10 ;;;; $Id$
11 ;;;;
12 ;;;; This file, part of KMRCL, is Copyright (c) 2002 by Kevin M. Rosenberg
13 ;;;;
14 ;;;; KMRCL users are granted the rights to distribute and use this software
15 ;;;; as governed by the terms of the Lisp Lesser GNU Public License
16 ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL.
17 ;;;; *************************************************************************
18
19
20 (in-package #:kmrcl)
21
22 (defun deriv (f dx)
23   #'(lambda (x)
24       (/ (- (funcall f (+ x dx)) (funcall f x))
25          dx)))
26
27 (defun sin^ (x)
28     (funcall (deriv #'sin 1d-8) x))
29
30 ;;; (sin^ pi)
31
32 (defmacro ensure-integer (obj)
33   "Ensure object is an integer. If it is a string, then parse it"
34   `(if (stringp ,obj)
35       (parse-integer ,obj)
36      ,obj))
37
38 (defun histogram (v n-bins &key min max)
39   (declare (fixnum n-bins))
40   (when (listp v)
41     (setq v (coerce v 'vector)))
42   (when (zerop (length v))
43     (return-from histogram (values nil nil nil)) )
44   (let ((n (length v))
45         (bins (make-array n-bins :element-type 'integer :initial-element 0))
46         found-min found-max)
47     (declare (fixnum n))
48     (unless (and min max)
49       (setq found-min (aref v 0)
50             found-max (aref v 0))
51       (loop for i fixnum from 1 to (1- n)
52           do
53             (let ((x (aref v i)))
54               (cond
55                ((> x found-max)
56                 (setq found-max x))
57                ((< x found-min)
58                 (setq found-min x)))))
59       (unless min
60         (setq min found-min))
61       (unless max
62         (setq max found-max)))
63     (let ((width (/ (- max min) n-bins)))
64       (setq width (+ width (* double-float-epsilon width)))
65       (dotimes (i n)
66         (let ((bin (nth-value 0 (truncate (- (aref v i) min) width))))
67           (declare (fixnum bin))
68           (when (and (not (minusp bin))
69                      (< bin n-bins))
70             (incf (aref bins bin))))))
71     (values bins min max)))
72               
73
74 (defun fixnum-width ()
75   (nth-value 0 (truncate (+ (/ (log (1+ most-positive-fixnum)) (log 2)) .5))))