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