Scheme Programming Language - scheme

I am trying to write a scheme program, but I am trying to figure out how can i do this:
suppose, I have called a function named addFunc, that takes two input numbers,
computes the sum squares of each number and returns the sum of the two sum
squares
in math, : if addFunc were called with 3 and 2, it will computer the sum squares of 3 as 1*1
+ 2*2 + 3*3 = 14 and sum squares of 2 as 1*1 + 2*2 = 5 and then returns 19 as a
result.
how can i write this in scheme programing language?

SICP is a good resource for learning scheme.
(define (sum-of-squares x)
(if (= 1 x)
1
(+ (* x x) (sum-of-squares (- x 1)))))
(define (homework x y)
(+ (sum-of-squares x) (sum-of-squares y)))

Related

Writing a function that finds the smallest k such that the difference between x and a function

I am having trouble where my code feels incomplete and plain wrong. For my function (terms-needed x tol) I am supposed to find the smallest k such that the difference between x and (square (babylonian x k)) is less than tol (tolerance). In other words we are supposed to measure how large k needs to be in the function (babylonian x k) to provide a good approximation of the square root.
As of right now I am getting an error of "application: not a procedure;" with my code
(define (square x)
(* x x))
(define (first-value-k-or-higher x tol k)
(if (<= (x)
(square (babylonian x k)) tol)
k)
(first-value-k-or-higher x tol (+ k 1))
)
(define (terms-needed x tol)
(first-value-k-or-higher x tol 1))
We are supposed to use a helper-function (first-value-k-or-higher x tol k) that evaluates to k if (square (bablyonian x k)) is within tol of the argument x, otherwise calls itself recursively
with larger k.
This is the function that is needed to make (terms-needed x tol) work:
(define (babylonian x k)
(if (>= x 1)
(if (= k 0)
(/ x 2)
(* (/ 1 2) (+ (expt x (/ 1 2)) (/ x (expt x (/ 1 2))))))
1)
)
Here is the full text, providing the full context on what the problem is supposed to be.
We will now measure how large k needs to be in the above function to provide a good approximation
of the square root. You will write a SCHEME function (terms-needed x tol) that will
evaluate to the number of terms in the infinite sum needed to be within tol, that is, the smallest
k such that the difference between x and (square (babylonian x k)) is less than tol.
Remark 2. At first glance, the problem of defining (terms-needed x tol) appears a little challenging,
because it’s not at all obvious how to express it in terms of a smaller problem. But you might
consider writing a helper function (first-value-k-or-higher x tol k) that evaluates to k if
(square (bablyonian x k)) is within tol of the argument x, otherwise calls itself recursively
with larger k.
You have several problems.
First, you have parentheses around x in
(if (<= (x)
That's causing the error you're seeing, because it's trying to call the function named x, but x names a number, not a function.
Second, you're not calculating the difference between x and (square (babylonian x k)). Instead, you gave 3 arguments to <=.
Third, you're not making the recursive call when the comparison fails. It's outside the if, so it's being done all the time (if you make use of an editor's automatic indentation feature, you might have noticed this problem yourself).
Fourth, you need to get the absolute value of the difference, not just the difference itself. Otherwise, if the difference is a large negative number, you'll consider it within the tolerance, which it shouldn't be.
(define (first-value-k-or-higher x tol k)
(if (<= (abs (- x (square (babylonian x k))))
tol)
k
(first-value-k-or-higher x tol (+ k 1))))

cosine function calculating scheme

Im making a scheme program that calculates
cos(x) = 1-(x^2/2!)+(x^4/4!)-(x^6/6!).......
whats the most efficient way to finish the program and how would you do the alternating addition and subtraction, thats what I used the modulo for but doesnt work for 0 and 1 (first 2 terms). x is the intial value of x and num is the number of terms
(define cosine-taylor
(lambda (x num)
(do ((i 0 (+ i 1)))
((= i num))
(if(= 0 (modulo i 2))
(+ x (/ (pow-tr2 x (* i 2)) (factorial (* 2 i))))
(- x (/ (pow-tr2 x (* i 2)) (factorial (* 2 i))))
))
x))
Your questions:
whats the most efficient way to finish the program? Assuming you want use the Taylor series expansion and simply sum up the terms n times, then your iterative approach is fine. I've refined it below; but your algorithm is fine. Others have pointed out possible loss of precision issues; see below for my approach.
how would you do the alternating addition and subtraction? Use another 'argument/local-variable' of odd?, a boolean, and have it alternate by using not. When odd? subtract when not odd? add.
(define (cosine-taylor x n)
(let computing ((result 1) (i 1) (odd? #t))
(if (> i n)
result
(computing ((if odd? - +) result (/ (expt x (* 2 i)) (factorial (* 2 i))))
(+ i 1)
(not odd?)))))
> (cos 1)
0.5403023058681398
> (cosine-taylor 1.0 100)
0.5403023058681397
Not bad?
The above is the Scheme-ish way of performing a 'do' loop. You should easily be able to see the correspondence to a do with three locals for i, result and odd?.
Regarding loss of numeric precision - if you really want to solve the precision problem, then convert x to an 'exact' number and do all computation using exact numbers. By doing that, you get a natural, Scheme-ly algorithm with 'perfect' precision.
> (cosine-taylor (exact 1.0) 100)
3982370694189213112257449588574354368421083585745317294214591570720658797345712348245607951726273112140707569917666955767676493702079041143086577901788489963764057368985531760218072253884896510810027045608931163026924711871107650567429563045077012372870953594171353825520131544591426035218450395194640007965562952702049286379961461862576998942257714483441812954797016455243/7370634274437294425723020690955000582197532501749282834530304049012705139844891055329946579551258167328758991952519989067828437291987262664130155373390933935639839787577227263900906438728247155340669759254710591512748889975965372460537609742126858908788049134631584753833888148637105832358427110829870831048811117978541096960000000000000000000000000000000000000000000000000
> (inexact (cosine-taylor (exact 1.0) 100))
0.5403023058681398
we should calculate the terms in iterative fashion to prevent the loss of precision from dividing very large numbers:
(define (cosine-taylor-term x)
(let ((t 1.0) (k 0))
(lambda (msg)
(case msg
((peek) t)
((pull)
(let ((p t))
(set! k (+ k 2))
(set! t (* (- t) (/ x (- k 1)) (/ x k)))
p))))))
Then it should be easy to build a function to produce an n-th term, or to sum the terms up until a term is smaller than a pre-set precision value:
(define t (cosine-taylor-term (atan 1)))
;Value: t
(reduce + 0 (map (lambda(x)(t 'pull)) '(1 2 3 4 5)))
;Value: .7071068056832942
(cos (atan 1))
;Value: .7071067811865476
(t 'peek)
;Value: -2.4611369504941985e-8
A few suggestions:
reduce your input modulo 2pi - most polynomial expansions converge very slowly with large numbers
Keep track of your factorials rather than computing them from scratch each time (once you have 4!, you get 5! by multiplying by 5, etc)
Similarly, all your powers are powers of x^2. Compute x^2 just once, then multiply the "x power so far" by this number (x2), rather than taking x to the n'th power
Here is some python code that implements this - it converges with very few terms (and you can control the precision with the while(abs(delta)>precision): statement)
from math import *
def myCos(x):
precision = 1e-5 # pick whatever you need
xr = (x+pi/2) % (2*pi)
if xr > pi:
sign = -1
else:
sign = 1
xr = (xr % pi) - pi/2
x2 = xr * xr
xp = 1
f = 1
c = 0
ans = 1
temp = 0
delta = 1
while(abs(delta) > precision):
c += 1
f *= c
c += 1
f *= c
xp *= x2
temp = xp / f
c += 1
f *= c
c += 1
f *= c
xp *= x2
delta = xp/f - temp
ans += delta
return sign * ans
Other than that I can't help you much as I am not familiar with scheme...
For your general enjoyment, here is a stream implementation. The stream returns an infinite sequence of taylor terms based on the provided func. The func is called with the current index.
(define (stream-taylor func)
(stream-map func (stream-from 0)))
(define (stream-cosine x)
(stream-taylor (lambda (n)
(if (zero? n)
1
(let ((odd? (= 1 (modulo n 2))))
;; Use `exact` if desired...
;; and see #WillNess above; save 'last'; use for next; avoid expt/factorial
((if odd? - +) (/ (expt x (* 2 n)) (factorial (* 2 n)))))))))
> (stream-fold + 0 (stream-take 10 (stream-cosine 1.0)))
0.5403023058681397
Here's the most streamlined function I could come up with.
It takes advantage of the fact that the every term is multiplied by (-x^2) and divided by (i+1)*(i+2) to come up with the text term.
It also takes advantage of the fact that we are computing factorials of 2, 4, 6. etc. So it increments the position counter by 2 and compares it with 2*N to stop iteration.
(define (cosine-taylor x num)
(let ((mult (* x x -1))
(twice-num (* 2 num)))
(define (helper iter prev-term prev-out)
(if (= iter twice-num)
(+ prev-term prev-out)
(helper (+ iter 2)
(/ (* prev-term mult) (+ iter 1) (+ iter 2))
(+ prev-term prev-out))))
(helper 0 1 0)))
Tested at repl.it.
Here are some answers:
(cosine-taylor 1.0 2)
=> 0.5416666666666666
(cosine-taylor 1.0 4)
=> 0.5403025793650793
(cosine-taylor 1.0 6)
=> 0.5403023058795627
(cosine-taylor 1.0 8)
=> 0.5403023058681398
(cosine-taylor 1.0 10)
=> 0.5403023058681397
(cosine-taylor 1.0 20)
=> 0.5403023058681397

while loop in racket?

I am familiar with while loops in other languages but here I have written a small function that computes the derivative of a sum of terms but it only does the first 2 I was wondering if there was a way to alter this to take into account more than 2?
expressions, E, are represented as lists so 2x + 2y + x^3 is represented as (+ (* 2 x) (* 2 y) (expt x 3))
note that I already have functions written to compute the exponential but it is part of a sum and it stops after the first 2
(define (make-sum v1 v2)
(list '+ v1 v2))
(define (diff-sum x E)
(make-sum (diff x (first-operator E)) (diff x (last-operator E))))
In professional-level Racket, for loops are a standard approach to do something to a sequence. For example, the following produces a simple multiplication table:
(define numbers (list 1 2 3 4 5 6))
(for/list ([item numbers])
(list item (* item 2) (* item 3)))
It's a loop that walks through each number, processes it, and produces a new list of results. Fairly standard; almost every programming language has a notion of iteration across a collection.
In the kind of Racket that you'd have to write for an introductory computer science class, you might have to resort to explicit recursion or a higher order function like map instead, depending on your instructor. These other ways of expressing iteration have the same power as the above loop: we just phrase it a little differently.
For example, the same computation to create the small multiplication table above would be expressed as the following with explicit recursion:
(define (my-loop numbers)
(cond [(empty? numbers) '()]
[else
(define item (first numbers))
(cons (list item (* item 2) (* item 3))
(my-loop (rest numbers)))]))
(my-loop numbers)
and implicitly with the use of map:
(define (f item)
(list item (* item 2) (* item 3)))
(map f numbers)

Find the Hardy–Ramanujan number using R5RS scheme. Please suggest improvements in idiom and calculations.

I remember once going to see
[Srinivasa Ramanujan] when he was ill
at Putney. I had ridden in taxi cab
number 1729 and remarked that the
number seemed to me rather a dull one,
and that I hoped it was not an
unfavorable omen. "No," he replied,
"it is a very interesting number; it
is the smallest number expressible as
the sum of two cubes in two different
ways." [G. H. Hardy as told in "1729
(number)"]
In "Math Wrath" Joseph Tartakovsky says about this feat, "So what?
Give me two minutes and my calculator watch, and I'll do the same
without exerting any little gray cells." I don't know how
Mr. Tartakovsky would accomplish that proof on a calculator watch, but
the following is my scheme function that enumerates numbers starting
at 1 and stops when it finds a number that is expressable in two
seperate ways by summing the cubes of two positive numbers. And it
indeeds returns 1729.
There are two areas where I would appreciate suggestions for
improvement. One area is, being new to scheme, style and idiom. The other area is around the calculations. Sisc
does not return exact numbers for roots, even when they could be. For
example (expt 27 1/3) yields 2.9999999999999996. But I do get exact
retults when cubing an exact number, (expt 3 3) yields 27. My
solution was to get the exact floor of a cube root and then test
against the cube of the floor and the cube of the floor plus one,
counting as a match if either match. This solution seems messy and hard to reason about. Is there a more straightforward way?
; Find the Hardy-Ramanujan number, which is the smallest positive
; integer that is the sum of the cubes of two positivie integers in
; two seperate ways.
(define (hardy-ramanujan-number)
(let ((how-many-sum-of-2-positive-cubes
; while i^3 + 1 < n/1
; tmp := exact_floor(cube-root(n - i^3))
; if n = i^3 + tmp^3 or n = i^3 + (tmp + 1) ^3 then count := count + 1
; return count
(lambda (n)
(let ((cube (lambda (n) (expt n 3)))
(cube-root (lambda (n) (inexact->exact (expt n 1/3)))))
(let iter ((i 1) (count 0))
(if (> (+ (expt i 3) 1) (/ n 2))
count
(let* ((cube-i (cube i))
(tmp (floor (cube-root (- n cube-i)))))
(iter (+ i 1)
(+ count
(if (or (= n (+ cube-i (cube tmp)))
(= n (+ cube-i (cube (+ tmp 1)))))
1
0))))))))))
(let iter ((n 1))
(if (= (how-many-sum-of-2-positive-cubes n) 2)
n
(iter (+ 1 n))))))
Your code looks mostly fine, I see a few very minor things to comment on:
There's no need to define cube and cube-root at the innermost scope,
Using define for internal functions makes it look a little clearer,
This is related to the second part of your question: you're using inexact->exact on a floating point number which can lead to large rationals (in the sense that you allocate a pair of two big integers) -- it would be better to avoid this,
Doing that still doesn't solve the extra test that you do -- but that's only because you're not certain if you have the right number of if you missed by 1. Given that it should be close to an integer, you can just use round and then do one check, saving you one test.
Fixing the above, and doing it in one function that returns the number when it's found, and using some more "obvious" identifier names, I get this:
(define (hardy-ramanujan-number n)
(define (cube n) (expt n 3))
(define (cube-root n) (inexact->exact (round (expt n 1/3))))
(let iter ([i 1] [count 0])
(if (> (+ (cube i) 1) (/ n 2))
(hardy-ramanujan-number (+ n 1))
(let* ([i^3 (cube i)]
[j^3 (cube (cube-root (- n i^3)))]
[count (if (= n (+ i^3 j^3)) (+ count 1) count)])
(if (= count 2) n (iter (+ i 1) count))))))
I'm running this on Racket, and it looks like it's about 10 times faster (50ms vs 5ms).
Different Schemes behave differently when it comes to exact exponentiation: some return an exact result when possible, some an inexact result in all cases. You can look at ExactExpt, one of my set of implementation contrasts pages, to see which Schemes do what.

Continuation-Passing Style in Scheme?

I ran into this code on Wikipedia:
(define (pyth x y k)
(* x x (lambda (x2)
(* y y (lambda (y2)
(+ x2 y2 (lambda (x2py2)
(sqrt x2py2 k))))))))
The article says that that code is the Continuation-Passing version of another piece of code:
(define (pyth x y)
(sqrt (+ (* x x) (* y y))))
However, I'm quite confused: How does that even work? How do you multiply a number by a lambda here? (* x x (lambda ...))
In the Wikipedia example, * doesn't mean the same thing as * in the conventional example.
I would rewrite the Wikipedia example as:
(define (pyth x y k)
(cps-* x x (lambda (x2)
(cps-* y y (lambda (y2)
(cps-+ x2 y2 (lambda (x2py2)
(cps-sqrt x2py2 k))))))))
In this form, each of the cps-xxx functions perform the operation indicated and then pass the result to the last argument. You could call it like this:
(pyth 2 3 display)
which would multiply 2 and 3, giving 6, and then passing 6 to display. (Actually you would want to pass the result to a cps-display that displayed its initial argument(s) and then called another function specified as its last parameter).

Resources