random-distributions/flat.ss
#lang scheme/base
;;; PLT Scheme Science Collection
;;; random-distributions/flat.ss
;;; Copyright (c) 2004-2008 M. Douglas Williams
;;;
;;; This library is free software; you can redistribute it and/or
;;; modify it under the terms of the GNU Lesser General Public
;;; License as published by the Free Software Foundation; either
;;; version 2.1 of the License, or (at your option) any later version.
;;;
;;; This library is distributed in the hope that it will be useful,
;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
;;; Lesser General Public License for more details.
;;;
;;; You should have received a copy of the GNU Lesser General Public
;;; License along with this library; if not, write to the Free
;;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
;;; 02111-1307 USA.
;;;
;;; -------------------------------------------------------------------
;;;
;;; This code implements a flat (uniform) distribution.  It is based on
;;; the Random Number Distributions in the GNU Scientific Library.
;;;
;;; Version  Date      Description
;;; 0.9.0    08/06/04  This is the initial release of the flat
;;;                    distribution routines. (Doug Williams)
;;; 1.0.0    09/28/04  Marked as ready for Release 1.0.  Added
;;;                    contracts for functions.  (Doug Williams)
;;; 2.0.0    11/19/07  Added unchecked versions of functions and
;;;                    getting ready for PLT Scheme 4.0 (Doug Williams)
;;; 3.0.0    06/09/08  Changes required for V4.0.  (Doug Williams)

(require (lib "contract.ss"))

(provide
 (rename-out (random-flat unchecked-random-flat)
             (flat-pdf unchecked-flat-pdf)
             (flat-cdf unchecked-flat-cdf)))

(provide/contract
 (random-flat
  (case-> (->r ((r random-source?)
                (a real?)
                (b (>/c a)))
               real?)
          (->r ((a real?)
                (b (>/c a)))
               real?)))
 (flat-pdf
  (->r ((x real?)
        (a real?)
        (b (>/c a)))
       (>=/c 0.0)))
 (flat-cdf
  (->r ((x real?)
        (a real?)
        (b (>=/c a)))
       (real-in 0.0 1.0))))

(require "../random-source.ss")

;;; random-flat: random-source x real x real -> real
;;; random-flat: real x real -> real
;;; This function returns a random variate from the flat (uniform)
;;; distribution from a to b.
(define random-flat
  (case-lambda
    ((r a b)
     (let ((u (unchecked-random-uniform r)))
       (+ (* a (- 1 u)) (* b u))))
    ((a b)
     (random-flat (current-random-source) a b))))

;;; flat-pdf: real x real x real-> real
;;; This function computes the probability density p(x) at x for a
;;; flat (uniform) distribution from a to b.
(define (flat-pdf x a b)
  (if (< x a)
      ;; x < a
      0
      (if (<= x b)
          ;; a <= x <= b
          (/ 1.0 (- b a))
          ;; x > b
          0)))

;;; flat-cdf: real x real x real-> real
;;; This function computes the cummulative density d(x) at x for a
;;; flat (uniform) distribution from a to b.
(define (flat-cdf x a b)
  (if (< x a)
      ;; x < a
      0
      (if (<= x b)
          ;; a <= x <= c
          (/ (- x a) (- b a))
          ;; x > b
          1)))