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)
Related
I would like to see how the value of a square root is iteratively improved. For example on the following:
#lang sicp
(define (square x) (* x x))
(define (average x y) (/ (+ x y) 2))
(define (improve guess x) (average guess (/ x guess)))
(define (good-enough? guess x) (< (abs (- (square guess) x)) 0.001 ))
(define (sqrt-iter guess x) (if (good-enough? guess x) guess (sqrt-iter (improve guess x) x)))
(define (sqrt x) (sqrt-iter 1.0 x))
(sqrt 2)
It gets values such as the following:
1 1
2 1.5
3 1.4166666666666665
4 1.4142156862745097
As an example of what I want to show, in Javascript I would do something like:
const sqrt_iter = (guess, x) => {
console.log(count++, guess);
return good_enough(guess, x) ? guess : sqrt_iter(improve(guess, x), x);
}
const sqrt = x => sqrt_iter(1.0, x);
How could I print or trace these intermediate values in DrRacket/SICP? I tried doing (trace sqrt) but it said not found.
I am sure Racket has some fancy trace facility. But there's a famous quote (due I think to John Foderaro):
Lisp [for which read Racket] is the programmable programming language.
What this means is: if there's no tracing facility, or you are too lazy to make one, you can just write one.
Here is a rudimentary one I wrote in five minutes:
#lang racket
(provide define/traced)
(define trace-depths (make-parameter 0))
(define (spaces n)
(make-string n #\ ))
(define-syntax define/traced
(syntax-rules ()
[(_ (name arg ...) form ...)
(define/traced name (λ (arg ...) form ...))]
[(_ (name . args) form ...)
(define/traced name (λ args form ...))]
[(_ name function)
(define name
(λ args
(let* ([depth (trace-depths)]
[prefix (spaces depth)])
(parameterize ([trace-depths (+ depth 1)])
(printf "~A~S ...~%" prefix `(,'name ,#args))
(call-with-values
(thunk (apply function args))
(λ results
(printf "~A-> ~S~%" prefix results)
(apply values results)))))))]))
Stash this in a file called define-traced.rkt and then require it, and tell it to trace the procedures you care about:
#lang racket
(require "define-traced.rkt")
(define (square x) (* x x))
(define (average x y) (/ (+ x y) 2))
(define/traced (improve guess x) (average guess (/ x guess)))
(define (good-enough? guess x) (< (abs (- (square guess) x)) 0.001 ))
(define/traced (sqrt-iter guess x) (if (good-enough? guess x) guess (sqrt-iter (improve guess x) x)))
(define (sqrt x) (sqrt-iter 1.0 x))
(sqrt 2)
Which will duly print this:
(sqrt-iter 1.0 2) ...
(improve 1.0 2) ...
-> (1.5)
(sqrt-iter 1.5 2) ...
(improve 1.5 2) ...
-> (1.4166666666666665)
(sqrt-iter 1.4166666666666665 2) ...
(improve 1.4166666666666665 2) ...
-> (1.4142156862745097)
(sqrt-iter 1.4142156862745097 2) ...
-> (1.4142156862745097)
-> (1.4142156862745097)
-> (1.4142156862745097)
-> (1.4142156862745097)
1.4142156862745097
Note that when I said it was a rudimentary facility I meant it: in particular it will probably turn tail calls into non-tail calls, and there are many other things wrong with it. But it took less long to write than it would take to read the manual on some hairy facility. If I was going to use this thing just once (and this is probably the only time I will ever use it: it only made it into a file so I could require it in another file) it's worth it. This is one of the glories of Lisp-family languages.
Try begin with printf (and also add one variable as counter):
#lang racket
(define (square x)
(* x x))
(define (average x y)
(/ (+ x y) 2))
(define (improve guess x)
(average guess (/ x guess)))
(define (good-enough? guess x)
(< (abs (- (square guess) x)) 0.001 ))
(define (sqrt-iter guess x count)
(begin
(printf "~a ~a \n" count guess)
(if (good-enough? guess x)
guess
(sqrt-iter (improve guess x)
x
(+ 1 count)))))
(define (sqrt x) (sqrt-iter 1.0 x 1))
(sqrt 2)
1 1.0
2 1.5
3 1.4166666666666665
4 1.4142156862745097
1.4142156862745097
Note that I used #lang racket- it seems that sicp don't have print or printf, but you can try write or display to achieve similar result.
#ignis provides the proper technique for this. However, before you dive into the deep ocean of define-syntax, maybe you want the quick-and-dirty approach -
#lang sicp
(define (sqrt-iter guess x)
(for-each display (list "sqrt-iter" " " guess " " x "\n"))
(if (good-enough? guess x)
guess
(sqrt-iter (improve guess x) x)))
(sqrt 2)
sqrt-iter 1.0 2
sqrt-iter 1.5 2
sqrt-iter 1.4166666666666665 2
sqrt-iter 1.4142156862745097 2
1.4142156862745097
I'm sorry if this question has been answered before, but I've looked around and I can't really understand the explanation as to why I'm getting this error.
From what I understand I'm asking if a statement is true and then if it is I'm asking it to return an expression. And apparently I'm not allowed to get #t/#f answers and expressions? I'm not sure. Could someone help me understand.
This is my code.
(define (piecewise x)
(define pi 3.142)
(cond
((> x (* pi 2)) (- x (* 2 pi)))
((or ( > x (* pi -1) (= x ( * -1 pi)))) (sin x))
((or ( < x (* 2 pi)) (= x (* 2 pi))) (sin x))
(else (- (- 1 x) pi))))
If I may, if we take all of the suggestions and use them to simplify the code a bit, we might get the following:
(define (piecewise x)
(let* ((pi 3.142)
(tau (* 2 pi)))
(cond
((> x tau)
(- x tau))
((or (>= x (- pi))
(<= x tau))
(sin x))
(else (+ x pi)))))
This runs without errors under both Racket and Guile. Whether it computes the function correctly, only the OP can say for certain.
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!
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.
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.