How to produce a stream of guesses for the root of f? - scheme

I would like to produce a stream of guesses for the root of f with 3 arguments f fx and x with f = sin(x) and x = 3. I tried some code but i don't get it. I would appreciate it if you could provide me some help.
(define (stream f fx x)
(let ((x (3))
((f x) (sin x))
((fx x) (cos x)))
(cons-stream (x (stream f fx (x (- x (/ (f x) (fx x)))))))))
(stream f fx 3)

Your code is this (I've applied indentation to make the bracketing clearer):
(define (stream f fx x)
(let ((x (3))
((f x) (sin x))
((fx x) (cos x)))
(cons-stream (x (stream f fx (x (- x (/ (f x) (fx x))))
))
)))
(stream f fx 3)
You have a few mistakes in this:
(3) treats 3 as a procedure and tries to call it. You should have 3 instead.
You have put specific arguments 3, sin, cos inside the general function. It should be outside instead.
You have done (x (stream ...)) and (x (- x ..)) both treat x like a function, but it's a number.
So clearing up these mistakes the code will be more like this:
(define (stream f fx x)
(cons-stream x (stream f fx (- x (/ (f x) (fx x))))))
(let ((x 3)
(f (lambda (x) (sin x)))
(fx (lambda (x) (cos x))))
(stream f fx x))
lambda was used to define a local function. Hope that helps, Feel free to ask follow up questions if anything was unclear.

Related

Riemann integral formula to compute high-order function

SICP introduced Riemann integral formula in Chapter 1.3.1
(define (integral f a b dx)
(define (add-dx x) (+ x dx))
(* (sum f (+ a (/ dx 2.0)) add-dx b)
dx))
Apply it to a particular case
#+name: case-1.3.1-integral.scm
#+BEGIN_SRC scheme :session sicp
(define pi 3.141592653589793)
(define (integral2 f a b dx)
(define (add-dx x) (+ x dx))
(* (sum (f b)
(+ a (/ dx 2.0))
(lambda (x) (+ x dx))
b)
dx))
(define (f b)
(lambda (x) (/ 1 (sqrt
(- (sin x)
(sin b))))))
(* (integral2 f 0 (/ pi 6) 0.00001)
(sqrt (/ 40
(* 3 9.8))))
#+END_SRC
#+RESULTS: case-1.3.1-integral.scm
: 0.0-1.777598336021436i
Got a perfect answer 1.777598336021436
Then translate it to elisp
Start from small:
#+name: case-1.3.1-integral.el
#+begin_src emacs-lisp :session sicp :lexical t
(defun integral (f a b dx)
(* (sum f
(+ a (/ dx 2.0))
(lambda (x) (+ x dx))
b)
dx))
(defun sum(term a next b)
(if (> a b)
0
(+ (funcall term a)
(sum term (funcall next a) next b))))
(integral #'cube 0 1 0.01)
#+end_src
#+RESULTS: case-1.3.1-integral.el
: 0.24998750000000042
It works and thus use it to solve the previous problem
#+begin_src emacs-lisp :session sicp :lexical t
(defvar pi 3.141592653589793)
(defun integral (f a b dx)
(* (sum f
(+ a (/ dx 2.0))
(lambda (x) (+ x dx))
b)
dx))
(defun f (b)
(lambda (x) (/ 1 (sqrt
(- (sin x)
(sin b))))))
(defun integral2 (f a b dx)
(* (sum (funcall f b)
(+ a (/ dx 2.0))
(lambda (x) (+ x dx))
b)
dx))
(integral2 #'f 0 (/ pi 6) 0.01)
#+end_src
But it return a meaningless result
ELISP> (integral2 #'f 0 (/ pi 6) 0.01)
-0.0e+NaN
What's the problem?
The answer you obtained when using Scheme is a complex number, the result of calling sqrt (are you sure the Scheme code was correct in the first place? you should double-check it):
0.0-1.777598336021436i
Unfortunately, Elisp doesn't support complex numbers, that's why we get a NaN in there. But that's not the real problem; you should investigate why are you getting complex results in the Scheme code, an integral should not return complex values!

Scheme function definition how to do it

Use comp to define the pos-cos function:
pos-cos(x) =
cos(x) if cos(x) ≥ 0 else
−cos(x) if cos(x) < 0
(define (comp f g)
(lambda (x) (f (g x))))
(define (pos-cos x)
(if (< (comp (cos x) x) 0)
(* -1 (cos x))
(cos x)))
This is what I have so far. But it gives me an error saying contract violation. I am new to scheme and cannot figure out the error. Can someone please look over my code? Thank you.
I believe you're using function composition in the wrong place. Truth is, you don't need it at all...
(define (pos-cos x)
(if (< (cos x) 0)
(- (cos x))
(cos x)))
But ok - just to satisfy some arbitrary requirement, we can compose abs and cos to take the absolute value of the result of the cosine of x, that's equivalent to the if expression we had before:
(define (pos-cos x)
((comp abs cos) x))
Notice the double parentheses up there at the start of the second line? that's important! remember that when we apply comp it returns a new lambda, and we have to apply it again to x to obtain the expected result.

Racket Function with Two Arguments

I'm trying to review my final exam in R5RS, but having trouble with a simple problem. My professor isn't really helpful and I don't know anybody in my class. Can you help me?
The function ratio takes in two parameters f (function) and x (a number). I had to use a let statement. The scheme function is supposed to produced an outcome for:
f(x)+f(x+1)/f(x)
This is what I have so far:
(define (ratio f x)
(let ((f (+ x 1)))
(/ (+ x (+ f 1))
x)))
(ratio (lambda (x) (+ x 2)) 3)
I tried working with this for an hour, but still can't get the right answer.
Hint: let a = f(x) and let b = f(x + 1). What should the output be in terms of a and b?
In your solution, you bind f to the value of x + 1. So your solution is really calculating (x + (x + 2)) / x. You need to apply f to x, ie (f x).
Here is a start:
(define (ratio f x)
(let ((a (f x)) (b (f (+ x 1))))
...))
Math Scheme
f(x) (f x)
x+1 (+ x 1)
f(x+1) (f (+ x 1))
a/b (/ a b)
a/f(x) (/ a (f x))
f(x+1)/f(x) (/ (f (+ x 1)) (f x))
c + f(x+1)/f(x) ?
f(x) + f(x+1)/f(x) ?

Gaussian functions and currying in Scheme

I am currently trying to learn Scheme to run FDTD simulations and I am having trouble building a Gaussian function in 2 dimensions.
In a forum I found this possibility for 1D:
(define ( (gaussx sigma) x)
(exp (- (/ (vector3-dot x x) (* 2 sigma sigma)))))
which if I understood currying correctly is equivalent to:
(define (gauss sigma)
(lambda(x)
(exp (- (/ (vector3-dot x x) (* 2 sigma sigma))))))
Now I would like the function to be gaussian along both x and y directions but I don't understand why this doesn't work:
(define (gauss sigma)
(lambda(x)
(lambda(y)
(exp (- (/ (+ (vector3-dot y y) (vector3-dot x x)) (* 2 sigma sigma))))
When I call
(gauss 1)
I get the following message:
ERROR: Wrong type (expecting real number): # <procedure> #f (y)
Does someone see what I am doing wrong? I also tried other solutions but I don't seem to get the logics here...
Thanks a lot for your help!
Best regards
Mei
I don't think there's need for a double currying here, try this:
(define (gauss sigma)
(lambda (x y)
(exp (- (/ (+ (vector3-dot y y) (vector3-dot x x)) (* 2 sigma sigma))))))
Call it like this:
(define gauss-1 (gauss 1))
(gauss-1 some-x some-y)
But if you definitely need the double currying, this should work:
(define (gauss sigma)
(lambda (x)
(lambda (y)
(exp (- (/ (+ (vector3-dot y y) (vector3-dot x x)) (* 2 sigma sigma)))))))
Using it like this:
(define gauss-1 (gauss 1))
((gauss-1 some-x) some-y)

Convert to CPS (Continuation Passing Style)

How do I convert these procedures in Scheme to CPS form?
(lambda (x y)
((x x) y))
(lambda (x)
(lambda (f)
(f (lambda (y)
(((x x) f) y))))
((lambda (x) (x x)
(lambda (x) (x x))
*This is not any homework!
See Programming Languages, Application and Interpretation, starting around Chapter 15. Chapter 18 talks about how to do it automatically, but if you're not familiar with thinking about expressing a function that does "what to do next", you'll probably want to try the finger exercises first.
Don't have someone do it for you: you'll really want to understand the process and be able to do it by hand, independent of Scheme or otherwise. It comes up especially in Asynchronous JavaScript web programming, where you really have no choice but to do the transform.
In the CPS transform, all non-primitive functions need to now consume a function that represents "what-to-do-next". That includes all lambdas. Symmetrically, any application of a non-primitive function needs to provide a "what-to-do-next" function, and stuff the rest of the computation in that function.
So if we had a program to compute a triangle's hypothenuse:
(define (hypo a b)
(define (square x) (* x x))
(define (add x y) (+ x y))
(sqrt (add (square a)
(square b))))
and if we state that the only primitive applications here are *, +, and sqrt, then all the other function definitions and function calls need to be translated, like this:
(define (hypo/k a b k)
(define (square/k x k)
(k (* x x)))
(define (add/k x y k)
(k (+ x y)))
(square/k a
(lambda (a^2)
(square/k b
(lambda (b^2)
(add/k a^2 b^2
(lambda (a^2+b^2)
(k (sqrt a^2+b^2)))))))))
;; a small test of the function.
(hypo/k 2 3 (lambda (result) (display result) (newline)))
The last expression shows that you end up having to compute "inside-out", and that the transformation is pervasive: all lambdas in the original source program end up needing to take an additional argument, and all non-primitive applications need to stuff "what-to-do-next" as that argument.
Take a close look at section 17.2 of the cited book: it covers this, as well as 17.5, which talks about why you need to touch ALL the lambdas in the source program, so that the higher-order case works too.
As another example of the transform, applied for a higher-order case, let's say that we have:
(define (twice f)
(lambda (x)
(f (f x))))
Then the translation of something like this is:
(define (twice/k f k1)
(k1 (lambda ...)))
... because that lambda's just a value that can be passed to k1. But of course, the translation needs to run through the lambda as well.
We must first do the inner call to f with x (and remember that all non-primitive function applications need to pass an appropriate "what-to-do-next!"):
(define (twice/k f k1)
(k1 (lambda (x k2)
(f x (lambda (fx-val)
...)))))
... take that value and apply it again to f...
(define (twice/k f k1)
(k1 (lambda (x k2)
(f x (lambda (fx-val)
(f fx-val ...))))))
... and finally return that value to k2:
(define (twice/k f k1)
(k1 (lambda (x k2)
(f x (lambda (fx-val)
(f fx-val k2))))))
;; test. Essentially, ((twice square) 7)
(define (square/k x k) (k (* x x)))
(twice/k square/k
(lambda (squaresquare)
(squaresquare 7
(lambda (seven^4)
(display seven^4)
(newline)))))
You need to choose to what level you need/want to CPS-transform.
If you just want (lambda (x y) ((x x) y)) in continuation-passing(CP) style, then (lambda (k x y) (k ((x x) y))) will do fine.
If you want its arguments to be treated as being in CP style too, then you need a little more.
Suppose first that only the second argument (y) is in CP form and is thus really something like (lambda (k) (k y0)) and so needs to be called with some continuation to extract its value, then you would need:
(lambda (k x y)
(y (lambda (y0) (k ((x x) y0)) )) )
Finally assume that both x and y are in CP style. Then you would need something like:
(lambda (k x y)
(x (lambda (x0)
(x (lambda (x1)
(y (lambda (y0)
(k ((x0 x1) y0)) ))))
Here you have the freedom to reorder the calls to x and y. Or maybe you only need one call to x, because you know its value does not depend on the continuation it is called with. For example:
(lambda (k x y)
(y (lambda (y0)
(x (lambda (x0)
(k ((x0 x0) y0)) ))))
The other expressions you asked about can be transformed similarly.

Resources