median-percentile.lisp 3.27 KB
Newer Older
1 2
;; Median and percentile
;; Liam Healy, Sun Dec 31 2006 - 13:19
3
;; Time-stamp: <2012-01-13 12:01:12EST median-percentile.lisp>
4
;;
5
;; Copyright 2006, 2007, 2008, 2009, 2011 Liam M. Healy
6 7 8 9 10 11 12 13 14 15 16 17 18 19
;; Distributed under the terms of the GNU General Public License
;;
;; This program is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;;
;; This program 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 General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 21 22 23 24 25

(in-package :gsl)

;;; To do: stride other than 1 when that information is availble from
;;; the vector.

Liam Healy's avatar
Liam Healy committed
26 27
(defmfun median ((sorted-data vector))
  ("gsl_stats" :type "_median_from_sorted_data")
28
  (((grid:foreign-pointer sorted-data) :pointer) (1 :int) ((dim0 sorted-data) :sizet))
Liam Healy's avatar
Liam Healy committed
29 30
  :definition :generic
  :element-types :no-complex
31
  :c-return :double
32
  :inputs (sorted-data)
33 34
  :documentation			; FDL
  "The median value of sorted-data.  The elements of the array
35 36 37 38
   must be in ascending numerical order.  There are no checks to see
   whether the data are sorted, so the function #'sort should
   always be used first.
   When the dataset has an odd number of elements the median is the value
39
   of element (n-1)/2.  When the dataset has an even number of
40
   elements the median is the mean of the two nearest middle values,
41
   elements (n-1)/2 and n/2.  Since the algorithm for
42 43 44
   computing the median involves interpolation this function always returns
   a floating-point number, even for integer data types.")

Liam Healy's avatar
Liam Healy committed
45 46
(defmfun quantile ((sorted-data vector) fraction)
  ("gsl_stats" :type "_quantile_from_sorted_data")
47
  (((grid:foreign-pointer sorted-data) :pointer) (1 :int) ((dim0 sorted-data) :sizet)
48
   (fraction :double))
Liam Healy's avatar
Liam Healy committed
49 50
  :definition :generic
  :element-types :no-complex
51
  :c-return :double
52
  :inputs (sorted-data)
53
  :documentation			; FDL
Liam Healy's avatar
Liam Healy committed
54
  "A quantile value of sorted-data.  The
55 56 57 58 59 60 61
   elements of the array must be in ascending numerical order.  The
   quantile is determined by a fraction between 0 and 1.  For
   example, to compute the value of the 75th percentile
   'fraction should have the value 0.75.
   There are no checks to see whether the data are sorted, so the function
   #'sort should always be used first.
   \hbox{quantile} = (1 - \delta) x_i + \delta x_{i+1}
62 63 64
   where i is floor((n - 1)f) and \delta is (n-1)f - i.
   Thus the minimum value of the array (data[0*stride]) is given by
   'fraction equal to zero, the maximum value (data[(n-1)*stride]) is
65 66 67 68 69
   given by 'fraction equal to one and the median value is given by 'fraction
   equal to 0.5.  Since the algorithm for computing quantiles involves
   interpolation this function always returns a floating-point number, even
   for integer data types.")

liam's avatar
liam committed
70 71
;;; Examples and unit test

Liam Healy's avatar
Liam Healy committed
72
(save-test median-percentile
73
  (let ((vec #m(-3.21d0 1.0d0 12.8d0)))
liam's avatar
liam committed
74
     (median vec))
75
  (let ((vec #m(-18.0d0 -12.0d0 -3.21d0 0.5d0 1.0d0 2.7d0 12.8d0)))
liam's avatar
liam committed
76
     (quantile vec 0.75d0)))