package Ġsc ient ifik . k math . misc Ċ Ċ import Ġsc ient ifik . k math . linear . Point Ċ import Ġsc ient ifik . k math . operations . Extended Field Ċ import Ġsc ient ifik . k math . operations . Field Ċ import Ġsc ient ifik . k math . operations . sum Ċ import Ġsc ient ifik . k math . structures . as Buffer Ċ Ċ /* Ċ Ġ* ĠImplementation Ġof Ġbackward - mode Ġautomatic Ġdifferent iation . Ċ Ġ* ĠInitial Ġgist Ġby ĠRoman ĠE liz ar ov : Ġhttps :// gist . github . com / el izar ov / 1 ad 3 a 8 5 8 3 e 8 8 cb 6 ea 7 a 0 ad 0 9 bb 5 9 1 d 3 d Ċ Ġ*/ Ċ Ċ /** Ċ Ġ* ĠDifferent iable Ġvariable Ġwith Ġvalue Ġand Ġderivative Ġof Ġdifferent iation Ġ([ deriv ]) Ġresult Ċ Ġ* Ġwith Ġrespect Ġto Ġthis Ġvariable . Ċ Ġ*/ Ċ open Ġclass ĠVariable < T Ġ: ĠAny >( val Ġvalue : ĠT ) Ċ Ċ class ĠDer ivation Result < T Ġ: ĠAny >( ĊĠĠĠ Ġvalue : ĠT , ĊĠĠĠ Ġval Ġderiv : ĠMap < Variable < T >, ĠT >, ĊĠĠĠ Ġval Ġcontext : ĠField < T > Ċ ) Ġ: ĠVariable < T >( value ) Ġ{ ĊĠĠĠ Ġfun Ġderiv ( variable : ĠVariable < T >) Ġ= Ġderiv [ variable ] Ġ?: Ġcontext . zero ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġcompute Ġdiv ergence ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġdiv () Ġ= Ġcontext . run Ġ{ Ġsum ( deriv . values ) Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCompute Ġa Ġgradient Ġfor Ġvariables Ġin Ġgiven Ġorder ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġgrad ( var arg Ġvariables : ĠVariable < T >): ĠPoint < T > Ġ= Ġif Ġ( variables . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠ Ġerror (" Variable Ġorder Ġis Ġnot Ġprovided Ġfor Ġgradient Ġconstruction ") ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠ Ġvariables . map (:: deriv ). as Buffer () ĊĠĠĠ Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠRuns Ġdifferent iation Ġand Ġestab lishes Ġ[ Auto Diff Field ] Ġcontext Ġinside Ġthe Ġblock Ġof Ġcode . Ċ Ġ* Ċ Ġ* ĠThe Ġpartial Ġderivatives Ġare Ġplaced Ġin Ġargument Ġ` d ` Ġvariable Ċ Ġ* Ċ Ġ* ĠExample : Ċ Ġ* Ġ``` Ċ Ġ* Ġval Ġx Ġ= ĠVariable ( 2 ) Ġ// Ġdefine Ġvariable ( s ) Ġand Ġtheir Ġvalues Ċ Ġ* Ġval Ġy Ġ= Ġderiv Ġ{ Ġsq r ( x ) Ġ+ Ġ 5 Ġ* Ġx Ġ+ Ġ 3 Ġ} Ġ// Ġwrite Ġform ulate Ġin Ġderiv Ġcontext Ċ Ġ* ĠassertEquals ( 1 7 . 0 , Ġy . x ) Ġ// Ġthe Ġvalue Ġof Ġresult Ġ( y ) Ċ Ġ* ĠassertEquals ( 9 . 0 , Ġx . d ) Ġ Ġ// Ġdy / dx Ċ Ġ* Ġ``` Ċ Ġ*/ Ċ fun Ġ< T Ġ: ĠAny , ĠF Ġ: ĠField < T >> ĠF . deriv ( body : ĠAuto Diff Field < T , ĠF >. () Ġ-> ĠVariable < T >): ĠDer ivation Result < T > Ġ= ĊĠĠĠ ĠAuto Diff Context < T , ĠF >( this ). run Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġresult Ġ= Ġbody () ĊĠĠĠĠĠĠĠ Ġresult . d Ġ= Ġcontext . one // Ġcomputing Ġderivative Ġw . r . t Ġresult ĊĠĠĠĠĠĠĠ Ġrun Backward Pass () ĊĠĠĠĠĠĠĠ ĠDer ivation Result ( result . value , Ġderivatives , Ġthis @ deriv ) ĊĠĠĠ Ġ} ĊĊ Ċ abstract Ġclass ĠAuto Diff Field < T Ġ: ĠAny , ĠF Ġ: ĠField < T >> Ġ: ĠField < Variable < T >> Ġ{ ĊĊĠĠĠ Ġabstract Ġval Ġcontext : ĠF ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠPerforms Ġupdate Ġof Ġderivative Ġafter Ġthe Ġrest Ġof Ġthe Ġformula Ġin Ġthe Ġback - pass . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠFor Ġexample , Ġimplementation Ġof Ġ` sin ` Ġfunction Ġis : ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ``` ĊĠĠĠĠ Ġ* Ġfun ĠAD . sin ( x : ĠVariable ): ĠVariable Ġ= Ġderive ( Variable ( sin ( x . x )) Ġ{ Ġz Ġ-> Ġ// Ġcall Ġderive Ġwith Ġfunction Ġresult ĊĠĠĠĠ Ġ* ĠĠĠĠ Ġx . d Ġ+= Ġz . d Ġ* Ġcos ( x . x ) Ġ// Ġupdate Ġderivative Ġusing Ġchain Ġrule Ġand Ġderivative Ġof Ġthe Ġfunction ĊĠĠĠĠ Ġ* Ġ} ĊĠĠĠĠ Ġ* Ġ``` ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġabstract Ġfun Ġ< R > Ġderive ( value : ĠR , Ġblock : ĠF .( R ) Ġ-> ĠUnit ): ĠR ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠA Ġvariable Ġaccessing Ġinner Ġstate Ġof Ġderivatives . ĊĠĠĠĠ Ġ* ĠUse Ġthis Ġfunction Ġin Ġinner Ġbuild ers Ġto Ġavoid Ġcreating Ġadditional Ġderivative Ġbindings ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġabstract Ġvar ĠVariable < T >. d : ĠT ĊĊĠĠĠ Ġabstract Ġfun Ġvariable ( value : ĠT ): ĠVariable < T > ĊĊĠĠĠ Ġinline Ġfun Ġvariable ( block : ĠF . () Ġ-> ĠT ) Ġ= Ġvariable ( context . block ()) ĊĊĠĠĠ Ġ// ĠOver loads Ġfor ĠDouble Ġconstants ĊĊĠĠĠ Ġoperator Ġfun ĠNumber . plus ( that : ĠVariable < T >): ĠVariable < T > Ġ= ĊĠĠĠĠĠĠĠ Ġderive ( variable Ġ{ Ġthis @ plus . toDouble () Ġ* Ġone Ġ+ Ġthat . value Ġ}) Ġ{ Ġz Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthat . d Ġ+= Ġz . d ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġoperator Ġfun ĠVariable < T >. plus ( b : ĠNumber ): ĠVariable < T > Ġ= Ġb . plus ( this ) ĊĊĠĠĠ Ġoperator Ġfun ĠNumber . minus ( that : ĠVariable < T >): ĠVariable < T > Ġ= ĊĠĠĠĠĠĠĠ Ġderive ( variable Ġ{ Ġthis @ minus . toDouble () Ġ* Ġone Ġ- Ġthat . value Ġ}) Ġ{ Ġz Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthat . d Ġ-= Ġz . d ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġoperator Ġfun ĠVariable < T >. minus ( that : ĠNumber ): ĠVariable < T > Ġ= ĊĠĠĠĠĠĠĠ Ġderive ( variable Ġ{ Ġthis @ minus . value Ġ- Ġone Ġ* Ġthat . toDouble () Ġ}) Ġ{ Ġz Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis @ minus . d Ġ+= Ġz . d ĊĠĠĠĠĠĠĠ Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠAutomatic ĠDifferent iation Ġcontext Ġclass . Ċ Ġ*/ Ċ private Ġclass ĠAuto Diff Context < T Ġ: ĠAny , ĠF Ġ: ĠField < T >>( override Ġval Ġcontext : ĠF ) Ġ: ĠAuto Diff Field < T , ĠF >() Ġ{ ĊĊĠĠĠ Ġ// Ġthis Ġstack Ġcontains Ġpairs Ġof Ġblocks Ġand Ġvalues Ġto Ġapply Ġthem Ġto ĊĠĠĠ Ġprivate Ġvar Ġstack Ġ= ĠarrayOf Null s < Any ? >( 8 ) ĊĠĠĠ Ġprivate Ġvar Ġsp Ġ= Ġ 0 ĊĊĠĠĠ Ġinternal Ġval Ġderivatives Ġ= ĠHashMap < Variable < T >, ĠT >() ĊĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠA Ġvariable Ġcoup led Ġwith Ġits Ġderivative . ĠFor Ġinternal Ġuse Ġonly ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġclass ĠVariable With Deriv < T Ġ: ĠAny >( x : ĠT , Ġvar Ġd : ĠT ) Ġ: ĠVariable < T >( x ) ĊĊĊĠĠĠ Ġoverride Ġfun Ġvariable ( value : ĠT ): ĠVariable < T > Ġ= ĊĠĠĠĠĠĠĠ ĠVariable With Deriv ( value , Ġcontext . zero ) ĊĊĠĠĠ Ġoverride Ġvar ĠVariable < T >. d : ĠT ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġ( this Ġas ? ĠVariable With Deriv )?. d Ġ?: Ġderivatives [ this ] Ġ?: Ġcontext . zero ĊĠĠĠĠĠĠĠ Ġset ( value ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( this Ġis ĠVariable With Deriv ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġd Ġ= Ġvalue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġderivatives [ this ] Ġ= Ġvalue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Suppress (" UN CHECK ED _ CAST ") ĊĠĠĠ Ġoverride Ġfun Ġ< R > Ġderive ( value : ĠR , Ġblock : ĠF .( R ) Ġ-> ĠUnit ): ĠR Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġsave Ġblock Ġto Ġstack Ġfor Ġbackward Ġpass ĊĠĠĠĠĠĠĠ Ġif Ġ( sp Ġ>= Ġstack . size ) Ġstack Ġ= Ġstack . copyOf ( stack . size Ġ* Ġ 2 ) ĊĠĠĠĠĠĠĠ Ġstack [ sp ++] Ġ= Ġblock ĊĠĠĠĠĠĠĠ Ġstack [ sp ++] Ġ= Ġvalue ĊĠĠĠĠĠĠĠ Ġreturn Ġvalue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Suppress (" UN CHECK ED _ CAST ") ĊĠĠĠ Ġfun Ġrun Backward Pass () Ġ{ ĊĠĠĠĠĠĠĠ Ġwhile Ġ( sp Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġvalue Ġ= Ġstack [ -- sp ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġblock Ġ= Ġstack [ -- sp ] Ġas ĠF .( Any ?) Ġ-> ĠUnit ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontext . block ( value ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠBasic Ġmath Ġ(+ , Ġ- , Ġ*, Ġ/ ) ĊĊĊĠĠĠ Ġoverride Ġfun Ġadd ( a : ĠVariable < T >, Ġb : ĠVariable < T >): ĠVariable < T > Ġ= ĊĠĠĠĠĠĠĠ Ġderive ( variable Ġ{ Ġa . value Ġ+ Ġb . value Ġ}) Ġ{ Ġz Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġa . d Ġ+= Ġz . d ĊĠĠĠĠĠĠĠĠĠĠĠ Ġb . d Ġ+= Ġz . d ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġmultiply ( a : ĠVariable < T >, Ġb : ĠVariable < T >): ĠVariable < T > Ġ= ĊĠĠĠĠĠĠĠ Ġderive ( variable Ġ{ Ġa . value Ġ* Ġb . value Ġ}) Ġ{ Ġz Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġa . d Ġ+= Ġz . d Ġ* Ġb . value ĊĠĠĠĠĠĠĠĠĠĠĠ Ġb . d Ġ+= Ġz . d Ġ* Ġa . value ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġdivide ( a : ĠVariable < T >, Ġb : ĠVariable < T >): ĠVariable < T > Ġ= ĊĠĠĠĠĠĠĠ Ġderive ( variable Ġ{ Ġa . value Ġ/ Ġb . value Ġ}) Ġ{ Ġz Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġa . d Ġ+= Ġz . d Ġ/ Ġb . value ĊĠĠĠĠĠĠĠĠĠĠĠ Ġb . d Ġ-= Ġz . d Ġ* Ġa . value Ġ/ Ġ( b . value Ġ* Ġb . value ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġmultiply ( a : ĠVariable < T >, Ġk : ĠNumber ): ĠVariable < T > Ġ= ĊĠĠĠĠĠĠĠ Ġderive ( variable Ġ{ Ġk . toDouble () Ġ* Ġa . value Ġ}) Ġ{ Ġz Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġa . d Ġ+= Ġz . d Ġ* Ġk . toDouble () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġval Ġzero : ĠVariable < T > Ġget () Ġ= ĠVariable ( context . zero ) ĊĠĠĠ Ġoverride Ġval Ġone : ĠVariable < T > Ġget () Ġ= ĠVariable ( context . one ) Ċ } Ċ Ċ // ĠExtensions Ġfor Ġdifferent iation Ġof Ġvarious Ġbasic Ġmathematical Ġfunctions Ċ Ċ // Ġx Ġ^ Ġ 2 Ċ fun Ġ< T Ġ: ĠAny , ĠF Ġ: ĠField < T >> ĠAuto Diff Field < T , ĠF >. sqr ( x : ĠVariable < T >): ĠVariable < T > Ġ= ĊĠĠĠ Ġderive ( variable Ġ{ Ġx . value Ġ* Ġx . value Ġ}) Ġ{ Ġz Ġ-> ĊĠĠĠĠĠĠĠ Ġx . d Ġ+= Ġz . d Ġ* Ġ 2 Ġ* Ġx . value ĊĠĠĠ Ġ} Ċ Ċ // Ġx Ġ^ Ġ 1 / 2 Ċ fun Ġ< T Ġ: ĠAny , ĠF Ġ: ĠExtended Field < T >> ĠAuto Diff Field < T , ĠF >. sqrt ( x : ĠVariable < T >): ĠVariable < T > Ġ= ĊĠĠĠ Ġderive ( variable Ġ{ Ġsqrt ( x . value ) Ġ}) Ġ{ Ġz Ġ-> ĊĠĠĠĠĠĠĠ Ġx . d Ġ+= Ġz . d Ġ* Ġ 0 . 5 Ġ/ Ġz . value ĊĠĠĠ Ġ} Ċ Ċ // Ġx Ġ^ Ġy Ġ( const ) Ċ fun Ġ< T Ġ: ĠAny , ĠF Ġ: ĠExtended Field < T >> ĠAuto Diff Field < T , ĠF >. pow ( x : ĠVariable < T >, Ġy : ĠDouble ): ĠVariable < T > Ġ= ĊĠĠĠ Ġderive ( variable Ġ{ Ġpower ( x . value , Ġy ) Ġ}) Ġ{ Ġz Ġ-> ĊĠĠĠĠĠĠĠ Ġx . d Ġ+= Ġz . d Ġ* Ġy Ġ* Ġpower ( x . value , Ġy Ġ- Ġ 1 ) ĊĠĠĠ Ġ} Ċ Ċ fun Ġ< T Ġ: ĠAny , ĠF Ġ: ĠExtended Field < T >> ĠAuto Diff Field < T , ĠF >. pow ( x : ĠVariable < T >, Ġy : ĠInt ): ĠVariable < T > Ġ= Ġpow ( x , Ġy . toDouble ()) Ċ Ċ // Ġexp ( x ) Ċ fun Ġ< T Ġ: ĠAny , ĠF Ġ: ĠExtended Field < T >> ĠAuto Diff Field < T , ĠF >. exp ( x : ĠVariable < T >): ĠVariable < T > Ġ= ĊĠĠĠ Ġderive ( variable Ġ{ Ġexp ( x . value ) Ġ}) Ġ{ Ġz Ġ-> ĊĠĠĠĠĠĠĠ Ġx . d Ġ+= Ġz . d Ġ* Ġz . value ĊĠĠĠ Ġ} Ċ Ċ // Ġln ( x ) Ċ fun Ġ< T Ġ: ĠAny , ĠF Ġ: ĠExtended Field < T >> ĠAuto Diff Field < T , ĠF >. ln ( x : ĠVariable < T >): ĠVariable < T > Ġ= Ġderive ( ĊĠĠĠ Ġvariable Ġ{ Ġln ( x . value ) Ġ} Ċ ) Ġ{ Ġz Ġ-> ĊĠĠĠ Ġx . d Ġ+= Ġz . d Ġ/ Ġx . value Ċ } Ċ Ċ // Ġx Ġ^ Ġy Ġ( any ) Ċ fun Ġ< T Ġ: ĠAny , ĠF Ġ: ĠExtended Field < T >> ĠAuto Diff Field < T , ĠF >. pow ( x : ĠVariable < T >, Ġy : ĠVariable < T >): ĠVariable < T > Ġ= ĊĠĠĠ Ġexp ( y Ġ* Ġln ( x )) Ċ Ċ // Ġsin ( x ) Ċ fun Ġ< T Ġ: ĠAny , ĠF Ġ: ĠExtended Field < T >> ĠAuto Diff Field < T , ĠF >. sin ( x : ĠVariable < T >): ĠVariable < T > Ġ= ĊĠĠĠ Ġderive ( variable Ġ{ Ġsin ( x . value ) Ġ}) Ġ{ Ġz Ġ-> ĊĠĠĠĠĠĠĠ Ġx . d Ġ+= Ġz . d Ġ* Ġcos ( x . value ) ĊĠĠĠ Ġ} Ċ Ċ // Ġcos ( x ) Ċ fun Ġ< T Ġ: ĠAny , ĠF Ġ: ĠExtended Field < T >> ĠAuto Diff Field < T , ĠF >. cos ( x : ĠVariable < T >): ĠVariable < T > Ġ= ĊĠĠĠ Ġderive ( variable Ġ{ Ġcos ( x . value ) Ġ}) Ġ{ Ġz Ġ-> ĊĠĠĠĠĠĠĠ Ġx . d Ġ-= Ġz . d Ġ* Ġsin ( x . value ) ĊĠĠĠ Ġ}