Scheme: Accelerated Stream - scheme

From this example code I found online, which functions are the unaccelerated stream, the singly-accelrated stream, and the super-accelerated stream? Thank you in advance.
Cite: lawfulsamurai.blogspot.com/2009/01/sicp-section-35-streams.html
(define (log2-summands n)
(cons-stream (/ 1.0 n)
(stream-map - (log2-summands (+ n 1)))))
(define log2-stream
(partial-sums (log2-summands 1)))
(define log2-stream-euler
(euler-transform log2-stream))
(define log2-stream-accelerated
(accelerated-sequence euler-transform log2-stream))

Well, you didn't tell us what either a "singly-accelrated" or "super-accelerated" are, so it's hard to say where in the code they are. It's like playing "Where's Waldo", but without knowing what a "Waldo" is.
That said, I can see that log2-summands, euler-transform, make-tableau, and accelerated-sequence all return streams, so it seems like they'd be the candidates. Now, if we actually look at the blog post that you linked to, SICP Section 3.5 Streams, we read:
Straightforward summation using partial-sums. The value of log2 oscillates between 0.6687714031754279 and 0.7163904507944756 after 20
iterations.
(define log2-stream
(partial-sums (log2-summands 1)))
Log2 using Euler Transformation. Value converges to 0.6932106782106783 after 10 iterations.
(define log2-stream-euler
(euler-transform log2-stream))
Accelerated summation. Value converges to 0.6931488693329254 in 4 iterations.
(define log2-stream-accelerated
(accelerated-sequence euler-transform log2-stream))
It sounds like that the log2-stream, log2-stream-euler, and log2-stream-accelerated are, respectively, the "unaccelerated stream, the singly-accelrated stream, and the super-accelerated stream".

Related

How does this Scheme code return a value?

This code is taken from Sussman and Wisdom's Structure and Interpretation of Classical Mechanics, its purpose is to derive (close to) the smallest positive floating point the host machine supports.
https://github.com/hnarayanan/sicm/blob/e37f011db68f8efc51ae309cd61bf497b90970da/scmutils/src/kernel/numeric.scm
Running it in DrRacket results in 2.220446049250313e-016 on my machine.
My question, what causes this to even return a value? This code is tail recursive, and it makes sense at some point the computer can no longer divide by 2. Why does it not throw?
(define *machine-epsilon*
(let loop ((e 1.0))
(if (= 1.0 (+ e 1.0))
(* 2 e)
(loop (/ e 2)))))
*machine-epsilon*
This code is tail recursive, and it makes sense at some point the computer can no longer divide by 2. Why does it not throw?
No, the idea is different: at some point the computer still can divide by 2, but the result (e) becomes indistinguishable from 0 [upd: in the context of floating-point addition only - very good point mentioned in the comment] (e + 1.0 = 1.0, this is exactly what if clause is checking). We know for sure that the previous e was still greater than zero "from the machine point of view" (otherwise we wouldn't get to the current execution point), so we simply return e*2.
This form of let-binding is syntactic sugar for recursion.
You may avoid using too much syntax until you master the language and write as much as possible using the kernel language, to focus on essential problem. For example, in full SICP text, never is specified this syntactic sugar for iteration.
The r6rs definition for iteration is here.
The purpose of this code is not to find the smallest float that the machine can support: it is to find the smallest float, epsilon such that (= (+ 1.0 epsilon) 1.0) is false. This number is useful because it's the upper bound on the error you get from adding numbers In particular what you know is that, say, (+ x y) is in the range [(x+y)*(1 - epsilon), (x+y)*(1 + epsilon)], where in the second expression + &c mean the ideal operations on numbers.
In particular (/ *machine-epsilon* 2) is a perfectly fine number, as is (/ *machine-epsilon* 10000) for instance, and (* (/ *machine-epsilon* x) x) will be very close to *machine-epsilon* for many reasonable values of x. It's just the case that (= (+ (/ *machine-epsilon* 2) 1.0) 1.0) is true.
I'm not familiar enough with floating-point standards, but the number you are probably thinking of is what Common Lisp calls least-positive-double-float (or its variants). In Racket you can derive some approximation to this by
(define *least-positive-mumble-float*
;; I don't know what float types Racket has if it even has more than one.
(let loop ([t 1.0])
(if (= (/ t 2) 0.0)
t
(loop (/ t 2)))))
I am not sure if this is allowed to raise an exception: it does not in practice and it gets a reasonable-looking answer.
It becomes clearer when you get rid of the confusing named let notation.
(define (calculate-epsilon (epsilon 1.0))
(if (= 1.0 (+ 1.0 epsilon))
(* epsilon 2)
(calculate-epsilon (/ epsilon 2))))
(define *machine-epsilon* (calculate-epsilon))
Is what the code does actually.
So now we see for what the named let expression is good.
It defines locally the function and runs it. Just that the name of the function as loop was very imprecise and confusing and the naming of epsilon to e is a very unhappy choice. Naming is the most important thing for readable code.
So this example of SICP should be an example for bad naming choices. (Okay, maybe they did it by intention to train the students).
The named let defines and calls/runs a function/procedure. Avoiding it would lead to better code - since clearer.
In common lisp such a construct would be much clearer expressed:
(defparameter *machine-epsilon*
(labels ((calculate-epsilon (&optional (epsilon 1.0))
(if (= 1.0 (+ 1.0 epsilon))
(* epsilon 2)
(calculate-epsilon (/ epsilon 2)))))
(calculate-epsilon)))
In CLISP implementation, this gives: 1.1920929E-7

Having trouble with a function in Scheme

so i am trying to understand this piece of code, and after staring at it for far too long i decided to ask here if anyone could help me understand how and why it works
(define knock-knock
(letrec ([dig (lambda (i)
(cons (* i (list-ref knock-knock (- i 1)))
(dig (+ i 1))))])
(cons 1 (dig 1))))
the function is then called by name with the value:
(list-ref knock-knock 5)
So my main problem is that i can not see where the letrec would end. the other thing is that i am not given a list, so what is the 4th element in the list that i am supposed to reference in line 3?
First, a note: this is not normal Scheme, as it requires lazy evaluation.
In lazy evaluation, values are only computed when they are needed. So, for defining knock-knock, we can just do
(cons 1 <thunk: (dig 1)>)
i.e., we generate a pair, but we don't need the second element, so we defer its evaluation until later.
When we actually want to evaluate the second element, we will already have knock-knock defined, so we can reference it.
The next element is computed by taking the previous (i-1-st) element, and multiplies it by i. So this will generate the series {n!}: 1,1,2,6,24,...
A straightforward translation of this code to the (normally lazy) Haskell language goes like this:
knock :: [Int]
knock = 1 : dig 1
where dig i = (i * knock !! (i-1)) : dig (i+1)

Random Walk in Clojure

I have written the following piece of code for a random walk, which draws random values from {-1,1}.
(defn notahappyfoo [n]
(reverse (butlast (butlast (reverse (interleave (take n (iterate rand (- 0 1)))(take n (iterate rand 1))))))))
However, the code fails to generate a satisfactory walk. The main problem stems from the function rand. It's lower bound is 0, which forced the awkward code I wrote. Namely, the function interleave ends up causing wild shifts in the walk as values are forced to swing from positive to negative. It will be hard to garner any sense of a continuous path with this code.
I believe there should be an elegant form in Clojure to construct this walk. But I am not able to piece the right functions together to generate such a walk. The goals of the function I am looking to construct consist of lower and upper bounds for the random number. In the code above I have forced the interval -1 to 1. It would be nice to generalize this to -a and a. Moreover, how do I form a collection of random reals (floating points) between -a and a that has some notion of continuity?
You need a random function that takes a range
(defn myrand [a b]
(+ a (rand (- b a))))
You can then create a sequence
(def s (repeatedly #(myrand -1 1)))
finally you can use reductions to get a sample walk
(take 10 s)
(reductions + (take 10 s))

How to convert this code to Scheme

So basically this code's purpose is to simply print out the first n even numbers.
for (i = 0; i <=n; i+= 2)
{
print i;
}
Thing is though, I don't understand Scheme at all. So, help please.
There are several ways to convert the code in the question to Scheme. The first one I can think of:
(define (print-even n)
(let loop ((i 0))
(if (<= i n)
(begin
(print i)
(newline)
(loop (+ i 2))))))
Notice this:
The solution is written as a recursive procedure
Instead of a for loop, I'm using a construct called a named let, which permits the initialization of some iteration variables (i in this case, initialized to 0) and the repeated execution of a recursive procedure (loop in this case), producing an effect similar to a for, even in performance
The stop condition in the "loop" is handled with essentially the same expression: repeat the body of the iteration as long as (<= i n), when that condition becomes false, the iteration ends
The begin surrounds the body of the "loop", just as the curly braces {} do in the original code
The print procedure performs the expected operation; for readability I added a new line after printing each number
The increment part of the original loop i += 2 is handled by the expression (+ i 2), inside the recursive call
So you see, the process being executed is essentially the same, only the way to write it (the syntax!) is different. Give it a try, type this:
(print-even 6)
... And the following will get printed on the screen:
0
2
4
6
Another possible way to implement the procedure, more similar to the original code, although (this is completely subjective) less idiomatic than the previous one:
(define (print-even n)
(do ((i 0 (+ i 2))) ((> i n))
(print i)
(newline)))
Finally, if you're using Racket this will seem even more familiar to you:
#lang racket
(define (print-even n)
(for ((i (in-range 0 (+ n 1) 2)))
(print i)
(newline)))
The first big difference between Scheme and other languages is this: In Scheme, you do (almost) everything recursively.
To implement a simple loop, for instance, you would define a recursive function. This function would first check to see whether it's time to break out of the loop; if is is, it would return the final value. (There is no final value in this case, so it would just return something like (void) or '().) Otherwise, the function would do whatever it's supposed to do, then call itself again.
Any loop variables (such as i) become arguments to the function.
Hopefully this helps you understand how to do this.
The Scheme way to do something like this is using a recursive function like the one below.
(define (doit value n)
(if (<= value n)
(begin
;;...perform loop body with x...
(display value)(newline)
(doit (+ value 2) n))))
To call this function you call (doit 2 n) where n is your n in the for loop.
With regards to learning Scheme, I recommend the first two links below.
For additional information on Scheme see
SICP
How to Design Programs
Schemers
Related Stackoverflow Question
Scheme Cookbook Looping Constructs

hacker news algorithm in php?

This is the Hacker News ranking algorithm, which I think is a simple way of ranking things, espcially if users are voting on items, but I really dnt understand this, can this be converted to PHP, so I can understand it fully?
; Votes divided by the age in hours to the gravityth power.
; Would be interesting to scale gravity in a slider.
(= gravity* 1.8 timebase* 120 front-threshold* 1
nourl-factor* .4 lightweight-factor* .17 gag-factor* .1)
(def frontpage-rank (s (o scorefn realscore) (o gravity gravity*))
(* (/ (let base (- (scorefn s) 1)
(if (> base 0) (expt base .8) base))
(expt (/ (+ (item-age s) timebase*) 60) gravity))
(if (no (in s!type 'story 'poll)) .8
(blank s!url) nourl-factor*
(mem 'bury s!keys) .001
(* (contro-factor s)
(if (mem 'gag s!keys)
gag-factor*
(lightweight s)
lightweight-factor*
1)))))
Directly ripped from http://amix.dk/blog/post/19574 and translated to PHP from the Python:
function calculate_score($votes, $item_hour_age, $gravity=1.8){
return ($votes - 1) / pow(($item_hour_age+2), $gravity);
}
There are write-ups about how this algorithm works. A quick search discovered: How Hacker News ranking algorithm works.
Lisp can make things seem more complicated than they really are.

Resources