aboutsummaryrefslogtreecommitdiff
path: root/src/clojure/contrib/generic/math_functions.clj
blob: 77623cce69ffd0c687661925d0b74021e0cbafde (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
;; Generic interfaces for mathematical functions

;; by Konrad Hinsen
;; last updated March 23, 2009

;; Copyright (c) Konrad Hinsen, 2009. All rights reserved.  The use
;; and distribution terms for this software are covered by the Eclipse
;; Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
;; which can be found in the file epl-v10.html at the root of this
;; distribution.  By using this software in any fashion, you are
;; agreeing to be bound by the terms of this license.  You must not
;; remove this notice, or any other, from this software.

(ns clojure.contrib.generic.math-functions
  "Generic math function interface

   NOTE: This library is VERY experimental. It WILL change significantly
   with future release.

   This library defines generic versions of common mathematical functions
   such as sqrt or sin as multimethods that can be defined for any type."
  (:use [clojure.contrib.def :only (defmacro-)])
  (:require [clojure.contrib.generic.arithmetic :as ga]
	    [clojure.contrib.generic.comparison :as gc]))

(defmacro- defmathfn-1
  [name]
  (let [java-symbol (symbol "java.lang.Math" (str name))]
    `(do
       (defmulti ~name type)
       (defmethod ~name java.lang.Number
	 [~'x]
	 (~java-symbol ~'x)))))

(defn- two-types [x y] [(type x) (type y)])

(defmacro- defmathfn-2
  [name]
  (let [java-symbol (symbol "java.lang.Math" (str name))]
    `(do
       (defmulti ~name two-types)
       (defmethod ~name [java.lang.Number java.lang.Number]
	 [~'x ~'y]
	 (~java-symbol ~'x ~'y)))))

; List of math functions taken from
; http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Math.html
(defmathfn-1 abs)
(defmathfn-1 acos)
(defmathfn-1 asin)
(defmathfn-1 atan)
(defmathfn-2 atan2)
(defmathfn-1 ceil)
(defmathfn-1 cos)
(defmathfn-1 exp)
(defmathfn-1 floor)
(defmathfn-1 log)
(defmathfn-2 pow)
(defmathfn-1 rint)
(defmathfn-1 round)
(defmathfn-1 sin)
(defmathfn-1 sqrt)
(defmathfn-1 tan)

;
; Sign
;
(defmulti sgn type)
(defmethod sgn :default
  [x]
  (cond (gc/zero? x) 0
	(gc/> x 0) 1
	:else -1))

;
; Conjugation
;
(defmulti conjugate type)

(defmethod conjugate :default
  [x] x)

;
; Square
;
(defmulti sqr type)

(defmethod sqr :default
  [x]
  (ga/* x x))

;
; Approximate equality for use with floating point types
;
(defn approx=
  "Return true if the absolute value of the difference between x and y
   is less than eps"
  [x y eps]
  (gc/< (abs (ga/- x y)) eps))