[Apologies for cross-posting]

For the algorithmic differentiation: I have started an implementation 
(attached) of the jet machinery using a domain rather than the domain+package 
used in Smith et al.

This provides considerably faster differentiation than symbolic 
differentiation. For example:

g(x) == (1+x)^10000
eval(D(g(x),x), x=0.1) -- slow
g(jet(0.1)) -- fast!

I was not certain how to get x=jet(1.0) or eval(x^x, x=jet(2.0)) to work: any 
suggestions?

Sincerely, Mark,

On 02/19/2017 12:21 PM, Gabriel Dos Reis wrote:
It was available in a branch of OpenAxiom. Jacob wanted to rewrite for merging 
in the main trunk. He graduated and got a job, so did not get to rewrite it. I 
added the AST part of the work to the trunk, but the jet machinery remained in 
Jacob's branch.

Jacob: do you still have that?

-- Gaby


On Feb 19, 2017 3:15 AM, "Mark Clements" 
<mark.cleme...@ki.se<mailto:mark.cleme...@ki.se>> wrote:
Is the Axiom code for Smith's work on algorithmic differentiation
available?

http://www.axiomatics.org/~gdr/ad/issac07.pdf<http://www.axiomatics.org/%7Egdr/ad/issac07.pdf>
http://oaktrust.library.tamu.edu/bitstream/handle/1969.1/ETD-TAMU-2010-05-7823/SMITH-DISSERTATION.pdf

Sincerely, Mark Clements.

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! <http://sdm.link/slashdot> 
http://sdm.link/slashdot
_______________________________________________
open-axiom-devel mailing list
open-axiom-devel@lists.sourceforge.net<mailto:open-axiom-devel@lists.sourceforge.net>
https://lists.sourceforge.net/lists/listinfo/open-axiom-devel


)abbrev domain JET Jet
Jet(T: Ring): Public == Private where
  Public ==> CoercibleTo(OutputForm) with
    jet: (T, T) -> %
      ++ construct a jet value from a pair
    jet: (T) -> %
      ++ construct a jet value with delta=1
    Zero: () -> %
      ++ zero value
    One: () -> %
      ++ one value
    elt: (%, "value") -> T
      ++ retrieve the value field of a jet
    elt: (%, "delta") -> T
     ++ retrieve the delta field of a jet
    setelt: (%, "value", T) -> T
      ++ set the value field of a jet
    setelt: (%, "delta", T) -> T
      ++ set the delta field of a jet
    "+": (%, %) -> %
    "+": (T, %) -> %
    "+": (%, T) -> %
    "-": (%, %) -> %
    "-": (T, %) -> %
    "-": (%, T) -> %
    "*": (%, %) -> %
    "*": (T, %) -> %
    "*": (%, T) -> %
    "-": % -> %
    if T has OrderedRing then
      abs: % -> %
    if T has PartialOrder then
      "<": (%, %) -> Boolean
      ">": (%, %) -> Boolean
      "<=": (%, %) -> Boolean
      ">=": (%, %) -> Boolean
      "=": (%, %) -> Boolean
    if T has Field then
      "/": (%, %) -> %
      "/": (T, %) -> %
      "/": (%, T) -> %
    if T has TranscendentalFunctionCategory and T has Field then
      log: % -> %
    if T has TranscendentalFunctionCategory and T has Field and T has 
RadicalCategory then
      asin: % -> %
      acos: % -> %
      atan: % -> %
    if T has TranscendentalFunctionCategory then
      exp: % -> %
      "^": (%, %) -> %
      "^": (%, T) -> %
      "^": (T, %) -> %
      sin: % -> %
      cos: % -> %
      tan: % -> %
      sinh: % -> %
      cosh: % -> %
      tanh: % -> %
    if T has RadicalCategory and T has Field then
      sqrt: % -> %
  Private ==> add
    x, y : %
    z : T
    Rep := Record(val: T, der: T)
    jet(v,d) == [v, d]
    jet(v) == [v, 1$T]
    Zero() == jet(0$T, 0$T)
    One() == jet(1$T, 1$T)
    elt(jet: %, key: "value") == jet.val    
    elt(jet: %, key: "delta") == jet.der
    setelt(jet: %, key: "value", jetValue: T) == jet.val := jetValue
    setelt(jet: %, key: "delta", jetDelta: T) == jet.der := jetDelta
    coerce(x:%):OutputForm == 
      hconcat(('jet)::OutputForm, paren [ (x.val)::OutputForm, 
(x.der)::OutputForm ])
    x + y == jet(x.value + y.value, x.delta + y.delta)
    x + z == jet(x.value + z, x.delta)
    z + x == jet(z + x.value, x.delta)
    x - y == jet(x.value - y.value, x.delta - y.delta)
    x - z == jet(x.value - z, x.delta)
    z - x == jet(z - x.value, -x.delta)
    x * y == jet(x.value * y.value, x.delta*y.value + x.value*y.delta)
    x * z == jet(x.value * z, x.delta*z)
    z * x == jet(z * x.value, z*x.delta)
    -x == jet(-x.value, -x.delta)
    if T has OrderedRing then
      abs x == jet(abs(x.value), sign(x.value)*x.delta)
    if T has PartialOrder then
      x < y == x.value < y.value
      x > y == x.value > y.value
      x <= y == x.value <= y.value
      x >= y == x.value >= y.value
      x = y == x.value = y.value
    if T has Field then
      x / y == 
        r : T := x.value / y.value
        jet(r, (x.delta - r * y.delta) / y.value)
      x / z == 
        jet(x.value / z, x.delta / z)
      z / x == 
        jet(z / x.value, -z*x.delta / x.value / x.value)
    if T has TranscendentalFunctionCategory and T has Field then
      log x == jet(log(x.value), x.delta/x.value)
    if T has TranscendentalFunctionCategory and T has Field and T has 
RadicalCategory then
      asin x == jet(asin(x.value), x.delta/sqrt(1-x.value*x.value))
      acos x == jet(acos(x.value), -x.delta/sqrt(1-x.value*x.value))
      atan x == jet(atan(x.value), x.delta/(1+x.value*x.value))
    if T has TranscendentalFunctionCategory then
      exp x == jet(exp(x.value), x.delta*exp(x.value))
      x ^ z == jet(x.value ^ z, x.delta*z*x.value^(z-1))
      x ^ y == jet(x.value ^ y.value, log(x.value)*x.value^y.value*y.delta + 
x.delta*y.value*x.value^(y.value-1))
      z ^ x == jet(z ^ x.value, log(z)*z^x.value*x.delta)
      sin x == jet(sin(x.value), x.delta*cos(x.value))
      cos x == jet(cos(x.value), -x.delta*sin(x.value))
      tan x == jet(tan(x.value), x.delta*(1+tan(x.value)*tan(x.value)))
      sinh x == jet(sinh(x.value), x.delta*cosh(x.value))
      cosh x == jet(cosh(x.value), x.delta*sinh(x.value))
      tanh x == jet(tanh(x.value), x.delta*(1-tanh(x.value)*tanh(x.value)))
    if T has RadicalCategory and T has Field then
      sqrt x == jet(sqrt(x.value), x.delta/sqrt(x.value)/(1$T+1$T))

)if false
)cd /home/marcle/Home/axiom
)co Jet2.spad
JF ==> Jet Float

-- constructors
jet(1.0,2.0)
jet(1.0)
Zero()$Jet Float
One()$Jet Float

-- check some operators
g := operator 'g
h := operator 'h
Dgx(f) == (f,D(f(g(x)),x))
[Dgx(log), Dgx(exp), Dgx(-), Dgx(h), Dgx(sin), Dgx(cos), Dgx(tan), Dgx(asin), 
Dgx(acos), Dgx(atan), Dgx(sinh), Dgx(cosh), Dgx(tanh), Dgx(sqrt)]
Dgx2(f) == (f,D(f(g(x),h(x)),x))
[Dgx2(+),Dgx2(-),Dgx2(*),Dgx2(/),Dgx2(^)]
[f::(Float->Float) for f in [+,-,*,/,^]]


-- testing
testDeriv(f,value) == eval(D(f(),X),x=value) - f(jet(value)).delta
testDeriv(log,2.0)
testDeriv(exp,2.0)
testDeriv(-,2.0)
testDeriv(x +-> exp(exp(x)),2.0)
testDeriv(sin,2.0)
testDeriv(cos,2.0)
testDeriv(tan,2.0)
testDeriv(sinh,2.0)
testDeriv(cosh,2.0)
testDeriv(tanh,2.0)
testDeriv(asin,0.1)
testDeriv(acos,0.1)
testDeriv(atan,0.1)
testDeriv(x +-> x^(2*x),2.0)
testDeriv(sqrt,2.0)
testDeriv(x +-> exp(x)/sqrt(x),2.0)
testDeriv(x +-> exp(x)*sqrt(x),2.0)
testDeriv(x +-> x*x,2.0)
testDeriv(x +-> x+x,2.0)
testDeriv(x +-> 10*x,2.0)

jet(2.0,1.0)<=jet(2.0,1.0)
jet(1,2) <= jet(1,3)

g(x) == (1+x)^10000
eval(D(g(x),x), x=0.1) -- slow symbolic differentiation
g(jet(0.1)) -- fast algorithmic differentiation!

g(x) == x^exp(x)^exp(x)
eval(D(g(x),x),x=2.0)
g(jet(2.0))

fx(x, n) ==
  if n=0 then return 0 
  else
    a := 0
    b := x
    (a,b) := (0, x)
    for k in 1..(n-1) repeat
      h := b
      b := log(a+b)
      a := h
    b
fx(jet(2.0,1.0), 7)
eval(D(fx(x,7),x), x=2.0)

-- partial likelihood
-- Assume distinct ordered times
event := [true,false,false,true,true,false]
times := [i for i in 1..#event]
x := [1,0,1,1,0,1]
eta := [beta*xi for xi in x]
index := [i for i in 1..#event for e in event | e]
L := reduce(*,[exp(eta(i))/reduce(+,[exp(eta(j)) for j in i..#event]) for i in 
index])
l := reduce(+,[eta(i) - log(reduce(+,[exp(eta(j)) for j in i..#event])) for i 
in index])
-- eval(l,beta=jet(1.0)) -- fails. How do I get beta=jet(1.0) to work?

-- time-varying effect
f(beta,gamma) == reduce(+,[x.i*beta+x.i*times.i*gamma - 
log(reduce(+,[exp(x.j*beta+x.j*times.j*gamma) for j in i..#event])) for i in 
index])
f(x,y)
f(jet(1.0))
f(jet(1.0),3.0)

)endif
------------------------------------------------------------------------------
Announcing the Oxford Dictionaries API! The API offers world-renowned
dictionary content that is easy and intuitive to access. Sign up for an
account today to start using our lexical data to power your apps and
projects. Get started today and enter our developer competition.
http://sdm.link/oxford
_______________________________________________
open-axiom-devel mailing list
open-axiom-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/open-axiom-devel

Reply via email to