Paste: dual numbers
Author: | Jason Merrill |
Mode: | factor |
Date: | Sun, 8 Feb 2009 02:56:32 |
Plain Text |
USING: kernel math math.functions math.derivatives accessors words
generalizations sequences generic.parser fry locals compiler.units
continuations quotations combinators macros make ;
IN: math.dual
TUPLE: dual ordinary-part epsilon-part ;
C: <dual> dual
M: number ordinary-part>> ;
M: number epsilon-part>> drop 0 ;
: unpack-dual ( dual -- ordinary-part epsilon-part )
[ ordinary-part>> ] [ epsilon-part>> ] bi ;
<PRIVATE
: my-join ( seq glue -- seq )
[ '[ [ _ % ] [ , ] interleave ] ] keep make ;
: [derivative-at-point] ( derivative-list -- quot )
[ <reversed> ] [ length '[ _ nkeep ] ] bi my-join [ call ] compose ;
:: chain-rule ( derivative-list n -- x )
[ [ epsilon-part>> ] n napply ] n nkeep [ ordinary-part>> ] n napply
derivative-list [derivative-at-point] call
n narray sum ; inline
PRIVATE>
:: [dual-op] ( word -- quot )
word "derivative" word-prop :> derivative-list
derivative-list length :> n
n word '[ [ ordinary-part>> ] _ napply _ execute ] n
derivative-list n
'[
_ _ nkeep
_ _ chain-rule
<dual>
] ;
MACRO: dual-op ( word -- ) [dual-op] ;
: define-dual-method ( word -- )
[ \ dual swap create-method-in ] keep [dual-op] define ;
<< { sqrt exp log sin cos tan sinh cosh tanh atan }
[ define-dual-method ] each >>
: d+ ( x y -- x+y ) \ + dual-op ;
: d- ( x y -- x+y ) \ - dual-op ;
: d* ( x y -- x*y ) \ * dual-op ;
: d/ ( x y -- x/y ) \ / dual-op ;
: d^ ( x y -- x^y ) \ ^ dual-op ;
Author: | jwmerrill |
Mode: | factor |
Date: | Sun, 8 Feb 2009 03:07:24 |
Plain Text |
USING: kernel math math.functions math.derivatives.parser ;
IN: math.derivatives
DERIVATIVE: + [ 2drop ] [ 2drop ]
DERIVATIVE: - [ 2drop ] [ 2drop neg ]
DERIVATIVE: * [ nip * ] [ drop * ]
DERIVATIVE: / [ nip / ] [ sq / neg * ]
DERIVATIVE: ^ [ [ 1 - ^ ] keep * * ]
[ [ dup zero? ] 2dip [ 3drop 0 ] [ [ ^ ] keep log * * ] if ]
DERIVATIVE: sqrt [ 2 * / ]
DERIVATIVE: exp [ exp * ]
DERIVATIVE: log [ / ]
DERIVATIVE: sin [ cos * ]
DERIVATIVE: cos [ sin neg * ]
DERIVATIVE: tan [ sec sq * ]
DERIVATIVE: sinh [ cosh * ]
DERIVATIVE: cosh [ sinh * ]
DERIVATIVE: tanh [ sech sq * ]
DERIVATIVE: asin [ sq neg 1 + sqrt / ]
DERIVATIVE: acos [ sq neg 1 + sqrt neg / ]
DERIVATIVE: atan [ sq 1 + / ]
DERIVATIVE: asinh [ sq 1 + sqrt / ]
DERIVATIVE: acosh [ [ 1 + sqrt ] [ 1 - sqrt ] bi * / ]
DERIVATIVE: atanh [ sq neg 1 + / ]
Author: | jwmerrill |
Mode: | factor |
Date: | Sun, 8 Feb 2009 03:08:06 |
Plain Text |
USING: kernel parser words effects accessors sequences math.ranges ;
IN: math.derivatives.parser
: DERIVATIVE: scan-object dup stack-effect in>> length [1,b]
[ drop scan-object ] map "derivative" set-word-prop ; parsing
Author: | jwmerrill |
Mode: | factor |
Date: | Sun, 8 Feb 2009 03:08:51 |
Plain Text |
USING: kernel math math.functions math.dual assocs fry accessors ;
IN: automatic-differentiation
: lift ( quot -- quot' )
H{
{ + d+ }
{ - d- }
{ * d* }
{ / d/ }
{ ^ d^ }
}
substitute ;
: [1diff] ( quot -- quot' )
lift '[ 1 <dual> @ epsilon-part>> ] ;
: 1diff ( x quot -- y ) [1diff] call ; inline
Author: | jwmerrill |
Mode: | factor |
Date: | Sun, 8 Feb 2009 03:09:38 |
Plain Text |
USING: kernel tools.test automatic-differentiation math math.functions
math.constants math.dual ;
IN: automatic-differentiation.tests
[ t ] [ 0 [ sin ] 1diff 1.0 epsilon 10 * ~ ] unit-test
[ t ] [ 0 [ cos ] 1diff 0 epsilon 10 * ~ ] unit-test
[ 1 ] [ 8 [ 3 + ] 1diff ] unit-test
[ 3 5 ] [ 1 5 <dual> 2 d+ unpack-dual ] unit-test
[ 0 -1 ] [ 1 5 <dual> 1 6 <dual> d- unpack-dual ] unit-test
[ 2 1 ] [ 2 3 <dual> 1 -1 <dual> d* unpack-dual ] unit-test
[ -1/4 ] [ 2 [ 1 swap / ] 1diff ] unit-test
[ 2 ] [ 1 [ 2 ^ ] 1diff ] unit-test
[ 1/8 ] [ 4 [ sqrt ] 1diff ] unit-test
Author: | jwmerrill |
Mode: | factor |
Date: | Sun, 8 Feb 2009 04:21:06 |
Plain Text |
USING: kernel math math.functions math.derivatives accessors words
generalizations sequences generic.parser fry locals compiler.units
continuations quotations combinators macros make ;
IN: math.dual
TUPLE: dual ordinary-part epsilon-part ;
C: <dual> dual
M: number ordinary-part>> ;
M: number epsilon-part>> drop 0 ;
: unpack-dual ( dual -- ordinary-part epsilon-part )
[ ordinary-part>> ] [ epsilon-part>> ] bi ;
<PRIVATE
MACRO: weave ( n -- quot )
[ '[ [ ] _ ncurry ] ]
[ <reversed> [ '[ _ ndip ] ] map ]
bi
'[ @ _ cleave ] ;
MACRO: nspread ( quots n -- quot )
over empty? [ 2drop [ ] ] [
[ [ but-last ] dip ] [ [ peek ] dip ] 2bi swap
'[ [ _ _ nspread ] _ ndip @ ]
] if ;
:: chain-rule ( derivative-list n -- x )
[ [ epsilon-part>> ] n napply ] n nkeep [ ordinary-part>> ] n napply
n weave
derivative-list n 1+ nspread
n narray sum ; inline
PRIVATE>
:: [dual-op] ( word -- quot )
word "derivative" word-prop :> derivative-list
derivative-list length :> n
n word '[ [ ordinary-part>> ] _ napply _ execute ] n
derivative-list n
'[
_ _ nkeep
_ _ chain-rule
<dual>
] ;
MACRO: dual-op ( word -- ) [dual-op] ;
: define-dual-method ( word -- )
[ \ dual swap create-method-in ] keep [dual-op] define ;
<< { sqrt exp log sin cos tan sinh cosh tanh atan }
[ define-dual-method ] each >>
: d+ ( x y -- x+y ) \ + dual-op ;
: d- ( x y -- x+y ) \ - dual-op ;
: d* ( x y -- x*y ) \ * dual-op ;
: d/ ( x y -- x/y ) \ / dual-op ;
: d^ ( x y -- x^y ) \ ^ dual-op ;
New Annotation