Merge pull request #2 from mcgirjau/master
Add normal distribution, calculus, and basic math
This commit is contained in:
commit
dd7698b86d
33
src/tools/calculus.cljc
Normal file
33
src/tools/calculus.cljc
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
(ns tools.calculus)
|
||||||
|
|
||||||
|
(defonce ^:const dx 0.0001)
|
||||||
|
|
||||||
|
(defn deriv
|
||||||
|
"Returns the derivative of f evaluated at c. If called with only one argument,
|
||||||
|
it returns the derivative function."
|
||||||
|
([f c]
|
||||||
|
((deriv f) c))
|
||||||
|
([f]
|
||||||
|
(fn [x]
|
||||||
|
(/ (- (f (+ x dx)) (f x)) dx))))
|
||||||
|
|
||||||
|
(defn integrate
|
||||||
|
"Returns the definite integral of f over [a, b] using Simpson's method.
|
||||||
|
If called with only one argument (the function), returns the indefinite
|
||||||
|
integral, which takes as input a value x and (optionally) a constant c."
|
||||||
|
([f]
|
||||||
|
(fn this
|
||||||
|
([x] (this x 0))
|
||||||
|
([x c] (+ (integrate f 0 x) c))))
|
||||||
|
([f a b]
|
||||||
|
(let [n (/ 1 dx)
|
||||||
|
h (/ (- b a) n)]
|
||||||
|
(loop [i 1
|
||||||
|
sum1 (f (+ a (/ h 2)))
|
||||||
|
sum2 0]
|
||||||
|
(if (< i n)
|
||||||
|
(recur (inc i)
|
||||||
|
(+ sum1 (f (+ a (* h i) (/ h 2))))
|
||||||
|
(+ sum2 (f (+ a (* h i)))))
|
||||||
|
(* (/ h 6) (+ (f a) (f b) (* 4 sum1) (* 2 sum2))))))))
|
||||||
|
|
59
src/tools/distributions.cljc
Normal file
59
src/tools/distributions.cljc
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
(ns tools.distributions
|
||||||
|
(:require [tools.math :as math])
|
||||||
|
(:require [tools.calculus :as calculus]))
|
||||||
|
|
||||||
|
;; -----------------------------------------------------------------------------
|
||||||
|
;; NORMAL
|
||||||
|
;; -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
(defn- box-muller
|
||||||
|
"Given two uniformly distributed random variables (from 0 to 1), returns a
|
||||||
|
Standard Normal variable computed using the Box-Muller Transform."
|
||||||
|
[u1 u2]
|
||||||
|
(* (math/sqrt (* -2 (math/log u1)))
|
||||||
|
(math/cos (* 2 math/PI u2))))
|
||||||
|
|
||||||
|
(defn- normal-pdf
|
||||||
|
"Given a mean and standard deviation, returns the corresponding Normal
|
||||||
|
Probability Distribution Function."
|
||||||
|
[mu sigma]
|
||||||
|
(fn [x]
|
||||||
|
(* (/ 1 (* sigma (math/sqrt (* 2 math/PI))))
|
||||||
|
(math/exp (- (/ (math/pow (/ (- x mu) sigma) 2) 2))))))
|
||||||
|
|
||||||
|
(defn rand-norm
|
||||||
|
"Generates n Normally-distributed random variables with given mean and
|
||||||
|
standard deviation. If no parameters are provided, defaults to a
|
||||||
|
single random observation from a Standard Normal distribution.
|
||||||
|
Accepts an argument map with optional keys :n, :mu, and :sigma."
|
||||||
|
[{:keys [n mu sigma]
|
||||||
|
:or {n 1, mu 0, sigma 1}}]
|
||||||
|
(repeatedly n #(box-muller (rand 1) (rand 1))))
|
||||||
|
|
||||||
|
(defn pdf-norm
|
||||||
|
"Returns the value of the Normal Probability Distribution Function at a
|
||||||
|
particular value x. If no distributional parameters are provided, defaults to
|
||||||
|
the Standard Normal PDF.
|
||||||
|
Accepts an argument map with keys :x, and optionally :mu and :sigma."
|
||||||
|
[{:keys [x mu sigma]
|
||||||
|
:or {mu 0, sigma 1}}]
|
||||||
|
((normal-pdf mu sigma) x))
|
||||||
|
|
||||||
|
(defn cdf-norm
|
||||||
|
"Parameters: {:keys [x mu sigma]}
|
||||||
|
Returns the value of the Normal Cumulative Distribution Function at a
|
||||||
|
particular value x. If no distributional parameters are provided, defaults to
|
||||||
|
the Standard Normal CDF.
|
||||||
|
Accepts an argument map with keys :x, and optionally :mu and :sigma."
|
||||||
|
[{:keys [x mu sigma]
|
||||||
|
:or {mu 0, sigma 1}}]
|
||||||
|
(calculus/integrate (normal-pdf mu sigma) (- mu (* 6 sigma)) x))
|
||||||
|
|
||||||
|
(defn quant-norm
|
||||||
|
"For a given probability p, returns the corresponding value of the quantile
|
||||||
|
function (i.e. the inverse Cumulative Distribution Function). If no
|
||||||
|
distributional parameters are provided, defaults to Standard Normal quantiles.
|
||||||
|
Accepts an argument map with keys :p, and optionally :mu and :sigma."
|
||||||
|
[{:keys [p mu sigma]
|
||||||
|
:or {mu 0, sigma 1}}]
|
||||||
|
()) ; unfinished...
|
99
src/tools/math.cljc
Normal file
99
src/tools/math.cljc
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
(ns tools.math)
|
||||||
|
|
||||||
|
(defonce PI #?(:clj Math/PI
|
||||||
|
:cljs js/Math.PI))
|
||||||
|
|
||||||
|
(defonce E #?(:clj Math/E
|
||||||
|
:cljs js/Math.PI))
|
||||||
|
|
||||||
|
(defn abs
|
||||||
|
"Returns the absolute value of a number."
|
||||||
|
[x]
|
||||||
|
(if (neg? x) (- x) x))
|
||||||
|
|
||||||
|
(defn approx= [x y epsilon]
|
||||||
|
"Returns true if the absolute difference between x and y is less than or
|
||||||
|
equal to some specified error level, epsilon."
|
||||||
|
(<= (abs (- y x)) epsilon))
|
||||||
|
|
||||||
|
(defn ceil
|
||||||
|
"Returns the smallest integer greater than or equal to x."
|
||||||
|
[x]
|
||||||
|
#?(:clj (Math/ceil x)
|
||||||
|
:cljs (js/Math.ceil x)))
|
||||||
|
|
||||||
|
(defn cos
|
||||||
|
"Returns the cosine of an angle (specified in radians)."
|
||||||
|
[x]
|
||||||
|
#?(:clj (Math/cos x)
|
||||||
|
:cljs (js/Math.cos x)))
|
||||||
|
|
||||||
|
(defn exp
|
||||||
|
"Returns Euler's number (approx. 2.71) raised to the given power."
|
||||||
|
[x]
|
||||||
|
#?(:clj (Math/exp x)
|
||||||
|
:cljs (js/Math.exp x)))
|
||||||
|
|
||||||
|
(defn floor
|
||||||
|
"Returns the largest integer less than or equal to x."
|
||||||
|
[x]
|
||||||
|
#?(:clj (Math/floor x)
|
||||||
|
:cljs (js/Math.floor x)))
|
||||||
|
|
||||||
|
(defn log
|
||||||
|
"Returns the logarithm of x with the given base. If called with only one
|
||||||
|
argument, returns the natural logarithm (base e) of the given value."
|
||||||
|
([x base]
|
||||||
|
(/ (log x) (log base)))
|
||||||
|
([x]
|
||||||
|
#?(:clj (Math/log x)
|
||||||
|
:cljs (js/Math.log x))))
|
||||||
|
|
||||||
|
(defn pow
|
||||||
|
"Returns the value obtained by raising the first argument to the power of
|
||||||
|
the second argument."
|
||||||
|
[x n]
|
||||||
|
#?(:clj (Math/pow x n)
|
||||||
|
:cljs (js/Math.pow x n)))
|
||||||
|
|
||||||
|
(defn root
|
||||||
|
"Returns the root of x with base n."
|
||||||
|
[x n]
|
||||||
|
(pow x (/ 1 n)))
|
||||||
|
|
||||||
|
(defn round
|
||||||
|
"Returns the value of x rounded to the nearest integer."
|
||||||
|
[x]
|
||||||
|
#?(:clj (Math/round x)
|
||||||
|
:cljs (js/Math.round x)))
|
||||||
|
|
||||||
|
(defn sign
|
||||||
|
"Returns the 1 if the argument is positive, -1 if the argument is negative,
|
||||||
|
and 0 if the argument is zero."
|
||||||
|
[x]
|
||||||
|
(cond (< x 0) -1
|
||||||
|
(> x 0) 1
|
||||||
|
:else 0))
|
||||||
|
|
||||||
|
(defn sin
|
||||||
|
"Returns the sine of an angle (specified in radians)."
|
||||||
|
[x]
|
||||||
|
#?(:clj (Math/sin x)
|
||||||
|
:cljs (js/Math.sin x)))
|
||||||
|
|
||||||
|
(defn sqrt
|
||||||
|
"Returns the square root of the given value."
|
||||||
|
[x]
|
||||||
|
#?(:clj (Math/sqrt x)
|
||||||
|
:cljs (js/Math.sqrt x)))
|
||||||
|
|
||||||
|
(defn square
|
||||||
|
"Returns the square of the given value."
|
||||||
|
[x]
|
||||||
|
(* x x))
|
||||||
|
|
||||||
|
(defn tan
|
||||||
|
"Returns the tangent of an angle (specified in radians)."
|
||||||
|
[x]
|
||||||
|
#?(:clj (Math/tan x)
|
||||||
|
:cljs (js/Math.tan x)))
|
Loading…
x
Reference in New Issue
Block a user