Re: [q-lang-users] [Fwd: Why cant I differentiate]
Brought to you by:
agraef
From: Albert G. <Dr....@t-...> - 2007-06-09 13:45:40
|
Koray Erkan wrote: > I'm very new to Q. I've copied the following bits of code from a white > paper ("Why Functional Programming Matters") - making a few very minor > changes to meet Q's syntax requirements as needed. It doesn't run, and > my hunch is there's something wrong with the "repeat" bit of it. Well, you got quite close, but John Hughes' paper uses its own notation, so you still have to change a few things. Specifically, Hughes' 'repeat' is nowadays called 'iterate', and you also have to change the program to use Q's stream syntax instead of those 'nil' and 'cons' thingies (or do a s/nil/nil_stream/ and s/cons/cons_stream/). The resulting program is attached. AFAICT it works just fine, except that the floating point arithmetic will go bonkers if the deltas get too small: ==> def S = differentiate 1 (\X.ln X) 2 ==> S {easydiff (\X1 . ln X1) 2 1|map (easydiff (\X1 . ln X1) 2) (iterate halve (halve 1))} ==> S!0 0.405465108108164 ==> S!10 0.499877969409454 ==> S!20 0.49999988079071 ==> S!9999 nan Those numbers quite clearly converge to 0.5 = 1/2 = ln'(2). One more note, you might also wish to uncomment the call to 'lazy' in the definition of 'differentiate'. This makes Q memoize stream members so that the same members aren't computed over and over again. (In difference to Haskell, Q by default uses "non-strict" rather than truly "lazy" evaluation.) See the description of the "memoize" operator and the 'lazy' function in the chapter on special forms of the manual for an explanation of this. The manual can be found online at: http://q-lang.sourceforge.net/qdoc/qdoc.html > BTW Is there a way to "step" through the code ? Yes sure, there's a symbolic debugger, I use that a lot myself. :) Just say 'debug on'. Or, like in gdb, you can set a breakpoint at a certain function with 'break foo' (use 'tbreak' instead for temporary breakpoints). For instance: ==> debug detail=all ==> break easydiff ==> S!20 ! Break 0> easydiff.q, line 2: easydiff <<Function>> 2 9.5367431640625e-07 ==> (<<Function>> (2+9.5367431640625e-07)-<<Function>> 2)/ 9.5367431640625e-07 : l -1 2 easydiff F X H = (F (X+H) - F X) / H; : F \X1 . ln X1 : X 2 : H 9.5367431640625e-07 See Appendix D of the manual for an explanation of the debugger, it does need some time to get used to it but is actually quite powerful. It might also help to read chapter 7 of the manual first, which describes how expressions are evaluated in Q. HTH, Albert -- Dr. Albert Gr"af Dept. of Music-Informatics, University of Mainz, Germany Email: Dr....@t-..., ag...@mu... WWW: http://www.musikinformatik.uni-mainz.de/ag |