2009-02-12 23:13:16 -05:00
|
|
|
! Copyright (C) 2009 Jason W. Merrill.
|
|
|
|
! See http://factorcode.org/license.txt for BSD license.
|
|
|
|
USING: kernel math math.functions math.derivatives accessors
|
2009-02-19 22:21:31 -05:00
|
|
|
macros generic compiler.units words effects vocabs
|
|
|
|
sequences arrays assocs generalizations fry make
|
|
|
|
combinators.smart help help.markup ;
|
2009-02-12 23:13:16 -05:00
|
|
|
|
|
|
|
IN: math.dual
|
|
|
|
|
|
|
|
TUPLE: dual ordinary-part epsilon-part ;
|
|
|
|
|
|
|
|
C: <dual> dual
|
|
|
|
|
2015-07-18 23:14:22 -04:00
|
|
|
! Ordinary numbers implement the dual protocol by returning
|
2009-02-12 23:13:16 -05:00
|
|
|
! themselves as the ordinary part, and 0 as the epsilon part.
|
|
|
|
M: number ordinary-part>> ;
|
|
|
|
|
|
|
|
M: number epsilon-part>> drop 0 ;
|
|
|
|
|
|
|
|
: unpack-dual ( dual -- ordinary-part epsilon-part )
|
|
|
|
[ ordinary-part>> ] [ epsilon-part>> ] bi ;
|
|
|
|
|
|
|
|
<PRIVATE
|
|
|
|
|
|
|
|
: input-length ( word -- n ) stack-effect in>> length ;
|
|
|
|
|
|
|
|
MACRO: ordinary-op ( word -- o )
|
|
|
|
[ input-length ] keep
|
|
|
|
'[ [ ordinary-part>> ] _ napply _ execute ] ;
|
|
|
|
|
2015-07-18 23:14:22 -04:00
|
|
|
! Takes N dual numbers <o1,e1> <o2,e2> ... <oN,eN> and weaves
|
2009-02-12 23:13:16 -05:00
|
|
|
! their ordinary and epsilon parts to produce
|
|
|
|
! e1 o1 o2 ... oN e2 o1 o2 ... oN ... eN o1 o2 ... oN
|
2015-07-18 23:14:22 -04:00
|
|
|
! This allows a set of partial derivatives each to be evaluated
|
2009-02-12 23:13:16 -05:00
|
|
|
! at the same point.
|
2015-07-19 01:16:11 -04:00
|
|
|
MACRO: duals>nweave ( n -- quot )
|
2009-02-12 23:13:16 -05:00
|
|
|
dup dup dup
|
|
|
|
'[
|
2018-06-19 20:15:05 -04:00
|
|
|
[ [ epsilon-part>> ] _ napply ] _ nkeep
|
|
|
|
[ ordinary-part>> ] _ napply _ nweave
|
2009-02-12 23:13:16 -05:00
|
|
|
] ;
|
|
|
|
|
|
|
|
MACRO: chain-rule ( word -- e )
|
|
|
|
[ input-length '[ _ duals>nweave ] ]
|
|
|
|
[ "derivative" word-prop ]
|
2009-08-13 20:21:44 -04:00
|
|
|
[ input-length 1 + '[ _ nspread ] ]
|
2009-02-12 23:13:16 -05:00
|
|
|
tri
|
|
|
|
'[ [ @ _ @ ] sum-outputs ] ;
|
|
|
|
|
2018-06-19 20:15:05 -04:00
|
|
|
: set-dual-help ( dword word -- )
|
|
|
|
[
|
|
|
|
[
|
|
|
|
stack-effect [ in>> ] [ out>> ] bi append
|
2009-02-19 22:21:31 -05:00
|
|
|
[ dual ] { } map>assoc { $values } prepend
|
2018-06-19 20:15:05 -04:00
|
|
|
] [
|
|
|
|
[
|
|
|
|
{ $description } % "Version of " ,
|
|
|
|
{ $link } swap suffix ,
|
|
|
|
" extended to work on dual numbers." ,
|
|
|
|
] { } make
|
|
|
|
] bi* 2array
|
|
|
|
] keepd set-word-help ;
|
2009-02-19 22:21:31 -05:00
|
|
|
|
2009-02-12 23:13:16 -05:00
|
|
|
PRIVATE>
|
|
|
|
|
2015-07-19 01:16:11 -04:00
|
|
|
MACRO: dual-op ( word -- quot )
|
2009-02-18 21:28:48 -05:00
|
|
|
[ '[ _ ordinary-op ] ]
|
|
|
|
[ input-length '[ _ nkeep ] ]
|
|
|
|
[ '[ _ chain-rule ] ]
|
2009-02-12 23:13:16 -05:00
|
|
|
tri
|
|
|
|
'[ _ @ @ <dual> ] ;
|
|
|
|
|
2009-02-19 18:49:13 -05:00
|
|
|
: define-dual ( word -- )
|
2018-06-19 20:15:05 -04:00
|
|
|
[ name>> "d" prepend "math.dual" create-word ] keep
|
|
|
|
[ stack-effect set-stack-effect ]
|
2009-02-19 22:21:31 -05:00
|
|
|
[ set-dual-help ]
|
2018-06-19 20:15:05 -04:00
|
|
|
[ '[ _ dual-op ] define ]
|
2009-02-19 22:21:31 -05:00
|
|
|
2tri ;
|
2009-02-12 23:13:16 -05:00
|
|
|
|
|
|
|
! Specialize math functions to operate on dual numbers.
|
2009-02-19 18:49:13 -05:00
|
|
|
[ all-words [ "derivative" word-prop ] filter
|
2018-06-19 20:15:05 -04:00
|
|
|
[ define-dual ] each ] with-compilation-unit
|