Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file owl_algodiff_generic.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176# 1 "src/base/optimise/algodiff/owl_algodiff_generic.ml"(*
* OWL - OCaml Scientific and Engineering Computing
* Copyright (c) 2016-2019 Liang Wang <liang.wang@cl.cam.ac.uk>
* Core nested automatic differentiation algorithm and differentiation API
* ported from DiffSharp (http://diffsharp.github.io), copyright (c) 2014-2016
* National University of Ireland Maynooth (Atilim Gunes Baydin), 2014-2018
* National University of Ireland Maynooth (Barak A. Pearlmutter
* <barak@pearlmutter.net>), 2016-2018 University of Oxford (Atilim Gunes
* Baydin <gunes@robots.ox.ac.uk>), 2017-2018 Microsoft Research Cambridge
* (Don Syme <dsyme@microsoft.com>
*)(* Functor of making AD module of different precisions *)moduleMake(A:Owl_types_ndarray_algodiff.Sig)=struct(* generate global tags *)let_global_tag=ref0lettag()=_global_tag:=!_global_tag+1;!_global_tag(* include functions in the Core module *)moduleCore=Owl_algodiff_core.Make(Owl_algodiff_types.Make(A))includeCore(* include graph conversion functions *)includeOwl_algodiff_graph_convert.Make(Core)(* instantiate operations *)moduleOps=Owl_algodiff_ops.Make(Core)moduleMaths=Ops.MathsmoduleMat=Ops.MatmoduleArr=Ops.ArrmoduleLinalg=Ops.LinalgmoduleNN=Ops.NN(* include core reverse mode functions *)moduleReverse=Owl_algodiff_reverse.Make(Core)includeReverse(* convenient wrappers *)letmake_forwardpti=DF(p,t,i)letmake_reversepi=letadjoint_cp_cat=tinletregistert=tinletlabel="Noop",[]inDR(p,ref(zerop),(adjoint,register,label),ref0,i,ref0)(* derivative of f (scalar -> scalr) at x, forward ad *)letdiff'fx=letx=make_forwardx(pack_flt1.)(tag())inlety=fxinprimaly,tangenty(* derivative of f (scalar -> scalar) at x, forward ad *)letdifffx=diff'fx|>snd(* gradient of f (vector -> scalar) at x, reverse ad *)letgrad'fx=letx=make_reversex(tag())inlety=fxinreverse_resety;reverse_push(pack_flt1.)y;primaly,x|>adjval(* gradient of f (vector -> scalar) at x, reverse ad *)letgradfx=grad'fx|>snd(* jacobian vector product of f (vector -> vector) at x along v, forward ad *)letjacobianv'fxv=letx=make_forwardxv(tag())inlety=fxinprimaly,tangenty(* jacobian vector product of f (vector -> vector) at x along v, forward ad *)letjacobianvfxv=jacobianv'fxv|>snd(* transposed jacobian vector product of f (vector -> vector) at x along v, backward ad *)letjacobianTv'fxv=letx=make_reversex(tag())inlety=fxinreverse_resety;reverse_pushvy;primaly,x|>adjval|>primal(* transposed jacobian vector product of f (vector -> vector) at x along v, backward ad *)letjacobianTvfxv=jacobianTv'fxv|>snd(* jacobian of f (vector -> vector) at x, both x and y are row vectors, also return the
original value *)letjacobian'fx=lety=fx|>primalinletm=col_numyinletn=col_numxinletz=A.empty[|m;n|]in(matchm>nwith|true->Array.initn(funi->letv=A.zeros[|1;n|]inA.(setv[|0;i|](float_to_elt1.));jacobianvfx(Arrv))|>Array.iteri(funiv->matchvwith|Arrv->A.copy_col_to(A.transposev)zi|_->failwith"error: jacobian")|false->Array.initm(funi->letv=A.zeros[|1;m|]inA.(setv[|0;i|](float_to_elt1.));jacobianTvfx(Arrv))|>Array.iteri(funiv->matchvwith|Arrv->A.copy_row_tovzi|_->failwith"error: jacobian"));y,Arrz(* jacobian of f *)letjacobianfx=jacobian'fx|>snd(* gradient, hessian of f (vector -> scalar) at [x] *)letgradhessianfx=jacobian'(gradf)x(* original value, gradient, and hessian *)letgradhessian'fx=letg,h=gradhessianfxinfx,g,h(* hessian of f *)lethessianfx=(f|>grad|>jacobian)x(* original value and hessian of f *)lethessian'fx=fx,hessianfx(* original value, gradient-vector product, hessian-vector product *)letgradhessianv'fxv=letgv,hv=grad'(funy->jacobianvfyv)xinfx,gv,hv(* gradient-vector product and hessian-vector product *)letgradhessianvfxv=let_,gv,hv=gradhessianv'fxvingv,hv(* original value and hessian-vector product *)lethessianv'fxv=letfv,_,hv=gradhessianv'fxvinfv,hv(* hessian-vector *)lethessianvfxv=let_,_,hv=gradhessianv'fxvinhv(* laplacian of f *)letlaplacianfx=F(hessianfx|>unpack_arr|>A.trace)letlaplacian'fx=fx,laplacianfxend(* ends here *)