Liking cljdoc? Tell your friends :D

Function Generics

Functions

In Emmy, functions are data just like other mathematical objects, and the generic arithmetic system is extended to include them. If <f> is an expression denoting a function, then:

(fn? <any>)         ;;=> <boolean>
(kind <f>)          ;;=> :emmy.value/function

Operations on functions generally construct new functions that are the composition of the operation with its arguments, thus applying the operation to the value of the functions: if U is a unary operation, if f is a function, and if x is arguments appropriate to f, then:

((U f) x) = (U (f x))

If B is a binary operation, if f and g are functions, and if x is arguments appropriate to both f and g, then:

((B f g) x) = (B (f x) (g x))

All of the usual unary operations are available. So if <f> is an expression representing a function, and if <x> is any kind of argument for <f> then, for example,

((negate <f>) <x>) = (negate (f <x>))
((invert <f>) <x>) = (invert (f <x>))
((sqrt <f>) <x>)   = (sqrt (f <x>))

The other operations that behave this way are:

exp, log, sin, cos, asin, acos, sinh, cosh, abs,
real-part, imag-part, magnitude, angle, conjugate, atan

The binary operations are similar, with the exception that mathematical objects that may not be normally viewed as functions are coerced to constant functions for combination with functions.

((+ <f> <g>) <x>) = (+ (f <x>) (g <x>))
((- <f> <g>) <x>) = (- (f <x>) (g <x>))

For example:

((+ sin 1) 'x) == (+ (sin 'x) 1)

The other operations that behave in this way are:

*, /, expt, gcd, make-rectangular, make-polar
All generic operations should work this way, so give them a try even if they’re not on the list.

Literal Functions

We often need literal functions in our computations. The object produced by (literal-function 'f) acts as a function of one real variable that produces a real result. The name (expression representation) of this function is the symbol 'f. This literal function has a derivative, which is the literal function with expression representation (D f). Thus, we may make up and manipulate expressions involving literal functions:

(freeze ((literal-function 'f) 3))
;;=>  (f 3)

(simplify ((D (* (literal-function 'f) cos)) 'a))
;;=> (+ (* ((D f) a) (cos a)) (* -1 (f a) (sin a)))

(simplify
 ((compose (D (* (literal-function 'f) cos))
           (literal-function 'g))
  'a))
;;=> (+ (* ((D f) (g a)) (cos (g a)))
        (* -1 (f (g a)) (sin (g a))))

We may use such a literal function anywhere that an explicit function of the same type may be used.

The Literal function descriptor language

We can also specify literal functions with multiple arguments and with structured arguments and results. For example, to denote a literal function named g that takes two real arguments and returns a real value ( g:RXR → R ) we may write:

(def g (literal-function 'g (-> (X Real Real) Real)))

(print-expression (g 'x 'y))
(g x y)

The descriptors for literal functions look like prefix versions of the standard function types. Thus, we write: (literal-function 'g (→ (X Real Real) Real))

The base types are the real numbers, designated by Real. We will later extend the system to include complex numbers, designated by Complex.

Types can be combined in several ways. The cartesian product of types is designated by:

(X <type1> <type2> ...)

We use this to specify an argument tuple of objects of the given types arranged in the given order.

Similarly, we can specify an up tuple or a down tuple with:

(UP <type1> <type2> ...)
(DOWN <type1> <type2> ...)

We can also specify a uniform tuple of a number of elements of the same type using:

(UP* <type> [n])
(DOWN* <type> [n])

So we can write specifications of more general functions:

(def H
  (literal-function 'H
                    (-> (UP Real (UP Real Real)
                            (DOWN Real Real))
                        Real)))

(def s (up 't (up 'x 'y) (down 'p_x 'p_y)))

(print-expression (H s))
;; (H (up t (up x y) (down p_x p_y)))

(print-expression ((D H) s))
;; (down
;;  (((partial 0) H) (up t (up x y) (down p_x p_y)))
;;  (down
;;   (((partial 1 0) H) (up t (up x y) (down p_x p_y)))
;;   (((partial 1 1) H) (up t (up x y) (down p_x p_y))))
;;  (up
;;   (((partial 2 0) H) (up t (up x y) (down p_x p_y)))
;;   (((partial 2 1) H) (up t (up x y) (down p_x p_y)))))

Can you improve this documentation?Edit on GitHub

cljdoc is a website building & hosting documentation for Clojure/Script libraries

× close