Scheme streams with Taylor series - stream

I've been doing some homework, wrote some code and can't actually find the reason why it doesn't work. The main idea of this part of the work is to make a stream that will give me elements of Taylor series of cosine function for a given X (angle i guess). anyways here is my code, I'd be happy if some one could point me to the reasons it doesn't work :)
(define (force exp) exp)
(define (s-car s) (car s))
(define (s-cdr s) (force (cdr s)))
; returns n elements of stream s as a list
(define (stream->list s n)
(if (= n 0)
'()
(cons (s-car s) (stream->list (s-cdr s) (- n 1)))))
; returns the n-th element of stream s
(define stream-ref (lambda (s n)
(if (= n 1)
(s-car s)
(stream-ref (s-cdr s) (- n 1)))))
; well, the name kinda gives it away :) make factorial n!
(define (factorial x)
(cond ((= x 0) 1)
((= x 1) 1)
(else (* x (factorial (- x 1))))))
; this function is actually the equation for the
; n-th element of Taylor series of cosine
(define (tylorElementCosine x)
(lambda (n)
(* (/ (expt -1 n) (factorial (* 2 n))) (expt x (* 2 n)))))
; here i try to make a stream of those Taylor series elements of cosine
(define (cosineStream x)
(define (iter n)
(cons ((tylorElementCosine x) n)
(lambda() ((tylorElementCosine x) (+ n 1)))))
(iter 0))
; this definition should bind cosine
; to the stream of taylor series for cosine 10
(define cosine (cosineStream 10))
(stream->list cosine 10)
; this should printi on screen the list of first 10 elements of the series
However, this doesn't work, and I don't know why.
I'm using Dr.Scheme 4.2.5 with the language set to "Essentials of Programming Languages 3rd ed".

Since I was feeling nice (and nostalgic about scheme) I actually waded through your code to finde the mistakes. From what I can see there are 2 problems which keeps the code from running as it should:
If I understand your code correctly (force exp) should evaluate exp, however you directly return it (unevaluated). So it probably should be defined as (define (force exp) (exp))
The second problem is in your lambda: (lambda() ((tylorElementCosine x) (+ n 1)) ) will evaluate to the next element of the taylor series, while it should evaluate to a stream. You probably want something like this: (lambda() (iter (+ n 1)) )
I haven't checked if the output is correct, but with those modifications it does at least run. So if there are any more problems with the code the should be in the formula used.
However I'd suggest that next time you want help with your homework you at least tell us where exactly the problem manifests and what you tried already (the community does frown on "here is some code, please fix it for me" kind of questions).

Related

Scheme: problem about display when using `delay` expression

This is a problem related to ex3.51 in SICP, here is the code
(define (cons-stream x y)
(cons x (delay y)))
(define (stream-car stream) (car stream))
(define (stream-cdr stream) (force (cdr stream)))
(define (stream-map proc s)
(if (stream-null? s)
the-empty-stream
(cons-stream
(proc (stream-car s))
(stream-map proc (stream-cdr s)))))
(define (stream-enumerate-interval low high)
(if (> low high)
the-empty-stream
(cons-stream
low
(stream-enumerate-interval (+ low 1) high))))
(define (stream-ref s n)
(if (= n 0)
(stream-car s)
(stream-ref (stream-cdr s) (- n 1))))
(define (show x)
(display x)
x)
;test
(stream-map show (stream-enumerate-interval 0 10))
the output is 012345678910(0 . #<promise>).
but I thought the delay expression in cons-stream delayed the evaluation, if i use a different processing function in stream-map like lambda (x) (+ x 1) the output (1 . #<promise>) is more reasonable, so why does display print all the numbers?
The problem is with this definition:
(define (cons-stream x y)
(cons x (delay y)))
It defines cons-stream as a function, since it uses define.
Scheme's evaluation is eager: the arguments are evaluated before the function body is entered. Thus y is already fully calculated when it is passed to delay.
Instead, cons-stream should be defined as a macro, like
(define-syntax cons-stream
(syntax-rules ()
((_ a b) (cons a (delay b)))))
or we can call delay explicitly, manually, like e.g.
(define (stream-map proc s)
(if (stream-null? s)
the-empty-stream
(cons
(proc (stream-car s))
(delay
(stream-map proc (stream-cdr s))))))
Then there'd be no calls to cons-stream in our code, only the (cons A (delay B)) calls. And delay is a macro (or special form, whatever), it does not evaluate its arguments before working but rather goes straight to manipulating the argument expressions instead.
And we could even drop the calls to delay, and replace (cons A (delay B)) with (cons A (lambda () B)). This would entail also reimplementing force (which is built-in, and goes together with the built-in delay) as simply (define (force x) (x)) or just calling the (x) manually where appropriate to force a stream's tail.
You can see such lambda-based streams code towards the end of this answer, or an ideone entry (for this RosettaCode entry) without any macros using the explicit lambdas instead. This approach can change the performance of the code though, as delay is memoizing but lambda-based streams are not. The difference will be seen if we ever try to access a stream's element more than once.
See also this answer for yet another take on streams implementation, surgically modifying list's last cons cell as a memoizing force.

Invocation Stack History Overflow

Been playing around with LISP in class. This is admittedly the first LISP code I've written. I can't figure out why this code produces the error "invocation stack history overflow" for input values over 2000 to the function (longest_collatz n). Can anyone with more experience in this language help me understand the error?
(defun longest_collatz(n)
(reverse
(maxlist
(loop for x from 1 to n
collect (list x (length (collatz x)))))))
(defun collatz (n)
(if (<= n 1)
'(1)
(if (= (mod n 2) 0)
(cons (/ n 2) (collatz (/ n 2)))
(cons (+ (* n 3) 1) (collatz (+ (* n 3) 1))))))
(defun maxlist (z)
(if (> (length z) 1)
(if (< (cadr (elt z 0)) (cadr (elt z 1)))
(maxlist (cdr z))
(maxlist (cons (elt z 0) (cddr z))))
(car z)))
Yout collatz function is not tail recursive, so it is unlikely that it is converted to a loop even if you compile your code.
You can rewrite it using an accumulator, so that it is converted to a loop by the compiler:
(defun collatz (n &optional acc)
(unless (plusp n)
(error "~s(~s): positive argument is required" 'collatz n))
(if (= n 1)
(nreverse (cons 1 acc))
(let ((next (if (evenp n)
(ash n -1) ; same as (mod n 2)
(1+ (* n 3)))))
(collatz next (cons next acc)))))
(this is a bug-for-bug reimplementation).
Notes:
Avoid elt; using first and second instead would be must better.
Rewriting maxlist using reduce would make it both faster and clearer.
Here's a function that just returns the length of the collatz list instead of the list itself. It could be more efficient (and is tail recursive).
(defun collatz_length2 (n cnt)
(if (<= n 1)
cnt
(if (= (mod n 2) 0)
(collatz_length2 (/ n 2) (1+ cnt))
(collatz_length2 (+ (* n 3) 1) (1+ cnt)))))
(defun collatz_length (n) (collatz_length2 n 1))

Infinite ascending sequence in Racket

Is there an analog of Python's itertools.count in Racket? I want to create an infinite stream of evenly spaced numbers. in-naturals is similar to what i want, but does not provide step. I'd want not to reinvent the wheel, but if there's no equivalent function, how to write one? (i presume, generators should be used)
You can get the same functionality of Python's count using in-range with an infinite end value:
(define (count start step)
(in-range start +inf.0 step))
For example:
(define s (count 2.5 0.5))
(stream-ref s 0)
=> 2.5
(stream-ref s 1)
=> 3.0
(stream-ref s 2)
=> 3.5
(stream-ref s 3)
=> 4.0
Making the function yourself can be done in a single line:
(define (stream-from n s) (stream-cons n (stream-from (+ n s) s)))
To test it, you here is an example that prints 100000 numbers:
#lang racket
(require racket/stream)
(define (stream-from n s) (stream-cons n (stream-from (+ n s) s)))
(define (stream-while s p)
(let ([fst (stream-first s)])
(if (p fst) (stream-cons fst (stream-while (stream-rest s) p)) empty-stream)))
(define test (stream-while (stream-from 0 1) (λ (x) (< x 100000))))
(stream-for-each println test)

Scheme: pattern matching syntax

This was an edit to an earlier post. I am reposting it because I think the original isn't getting any more views since I accepted a partial answer already.
I have written a function match-rewriter which is just match-lambda except that it returns its argument if no match is found.
Using match rewriter I want to be able to write rules that can be passed to another function rewrite which is this:
#| (rewrite rule s) repeatedly calls unary function 'rule' on every "part"
of s-expr s, in unspecified order, replacing each part with result of rule,
until calling rule makes no more changes to any part.
Parts are s, elements of s, and (recursively) parts of the elements of s. (define (rewrite rule s) |#
(let* ([with-subparts-rewritten
(if (list? s) (map (λ (element) (rewrite rule element)) s) s)]
[with-also-rule-self (rule with-subparts-rewritten)])
(if (equal? with-also-rule-self with-subparts-rewritten)
with-also-rule-self
(rewrite rule with-also-rule-self))))
Here is an example of proper usage:
(define arithmetic
(match-rewriter (`(+ ,a ,b) (+ a b))
(`(* ,a ,b) (* a b))
))
(rewrite arithmetic '(+ (* 2 (+ 3 4)) 5))
==>
19
Now I have written:
(define let→λ&call
(match-rewriter (`(let ((,<var> ,<val>) . (,<vars> ,<vals>)) ,<expr> . ,<exprs>)
`((λ (,<var> . ,<vars>) ,<expr> . ,<exprs>) ,<val> . ,<vals>))))
to implement lets as lambda calls, but this is how it is behaving:
(rewrite let→λ&call '(let((x 1) (y 2) (z 3)) (displayln x) (displayln y) (displayln z)))
'((λ (x y 2)
(displayln x)
(displayln y)
(displayln z))
1
z
3)
which, I have to say, really has me stumped. Strangely this call:
(rewrite let→λ&call '(let((w 0) (x 1) (y 2) (z 3)) (displayln w) (displayln x) (displayln y) (displayln z)))
'(let ((w 0) (x 1) (y 2) (z 3))
(displayln w)
(displayln x)
(displayln y)
(displayln z))
Just returns its argument, meaning that match-rewriter did not find a match for this pattern.
Any advice is appreciated.
Thanks.
This pattern:
((,<var> ,<val>) . (,<vars> ,<vals>))
does not do what you want. In particular, it's equivalent to:
((,<var> ,<val>) ,<vars> ,<vals>)
I recommend that you use regular match patterns, rather than quasi-patterns, until you have a better sense of how they work. The pattern for this would be:
(list (list <var> <val>) (list <vars> <vals>) ...)

Symbolic mathematical calculations in Clojure vs. F#

I have come across the following F# sample and found it intriguing.
http://www.codeproject.com/KB/net-languages/SymbolicCalcInFS.aspx
Does Clojure have language/library facilities for doing something like this with ease? It is ok to force Polish notation for formulas, if that makes things easier.
Thanks, and let me know if there are questions.
Lisp has long history in symbolic computing. See the AI case study book by Peter Norvig. Lisp provides a lot of great language features to abstract the common operations on the symbols. Sometimes you can write really concise code (more concise/short than F#).
Static languages like F# have strong type systems and convenient pattern matching on the data types. The compiler could find errors that are caught by the type system, e.g. lack of considering one special case. Thinking about types with your data could also reduce the chances for runtime error. The type inference in F# also makes F# code very concise.
I don't know much about Clojure, but here are, at least, some pointers.
The key feature that makes the F# code nice is pattern matching on algebraic data types. An algebraic data type is for example the declaration of the Expression type (that is used to represent mathematical expressions) and pattern matching is the match construct that is used to check for various known cases when implementing simplification or differentiation.
I don't think that Clojure has any built-in support for pattern matching, but it can be implemented as a library. One library that looks quite interesting is the patter-match module (in Clojars). Here is an example that uses it to implement algebraic evaluator (which is quite close to the F# article).
Another thing that appears in the F# article is active patterns (which allow you to declare and reuse patterns). I don't think that there is a Clojure library for that, but given the flexibility of the language, it should be possible to implement them too (however, they are not really that necessary in the F# article)
Symbolic differentiation was one of the first applications of lisp!
I made a blogpost about a simple symbolic differentiator. It only deals with + and *, but it is easily extended.
It was part of a series I wrote to introduce beginners to clojure at a conference in London, to show how easy it is for clojure to manipulate its own code.
Of course the cute thing is that having done the differentiation, the code can then be compiled! So you can produce differentiated versions of user input, or macros that produce functions and their derivatives, etc.
The original's here, and nicely syntax highlighted:
http://www.learningclojure.com/2010/02/clojure-dojo-4-symbolic-differentiation.html
But I've posted the code here so you can have a look:
;; The simplest possible symbolic differentiator
;; Functions to create and unpack additions like (+ 1 2)
(defn make-add [ a b ] (list '+ a b))
(defn addition? [x] (and (=(count x) 3) (= (first x) '+)))
(defn add1 [x] (second x))
(defn add2 [x] (second (rest x)))
;; Similar for multiplications (* 1 2)
(defn make-mul [ a b ] (list '* a b))
(defn multiplication? [x] (and (=(count x) 3) (= (first x) '*)))
(defn mul1 [x] (second x))
(defn mul2 [x] (second (rest x)))
;; Differentiation.
(defn deriv [exp var]
(cond (number? exp) 0 ;; d/dx c -> 0
(symbol? exp) (if (= exp var) 1 0) ;; d/dx x -> 1, d/dx y -> 0
(addition? exp) (make-add (deriv (add1 exp) var) (deriv (add2 exp) var)) ;; d/dx a+b -> d/dx a + d/dx b
(multiplication? exp) (make-add (make-mul (deriv (mul1 exp) var) (mul2 exp)) ;; d/dx a*b -> d/dx a * b + a * d/dx b
(make-mul (mul1 exp) (deriv (mul2 exp) var)))
:else :error))
;;an example of use: create the function x -> x^3 + 2x^2 + 1 and its derivative
(def poly '(+ (+ (* x (* x x)) (* 2 (* x x))) 1))
(defn poly->fnform [poly] (list 'fn '[x] poly))
(def polyfn (eval (poly->fnform poly)))
(def dpolyfn (eval (poly->fnform (deriv poly 'x))))
;;tests
(use 'clojure.test)
(deftest deriv-test
(testing "binary operators"
(is (= (let [m '(* a b)] [(multiplication? m) (make-mul (mul1 m) (mul2 m))]) [true '(* a b)]))
(is (= (let [m '(* a b)] [(addition? m) (make-add (add1 m) (add2 m))]) [false '(+ a b)])))
(testing "derivative function"
(is (= (deriv '0 'x) '0))
(is (= (deriv '1 'x) '0))
(is (= (deriv 'x 'x) '1))
(is (= (deriv 'y 'x) '0))
(is (= (deriv '(+ x x) 'x) '(+ 1 1)))
(is (= (deriv '(* x x) 'x) '(+ (* 1 x) (* x 1))))
(is (= (deriv '(* x x) 'y) '(+ (* 0 x) (* x 0))))
(is (= (deriv '(* x (* x x)) 'x) '(+ (* 1 (* x x)) (* x (+ (* 1 x) (* x 1)))))))
(testing "function creation: d/dx (x^3 + 2x^2 + 1) = 3x^2 + 4x "
(let [poly '(+ (+ (* x (* x x)) (* 2 (* x x))) 1)]
(is (= ((eval (poly->fnform poly)) 3) 46))
(is (= ((eval (poly->fnform (deriv poly 'x))) 3))))))
I haven't tried it, but Clojuratica looks very interesting.
Well, now Clojure offer powerful pattern matching libraries :
matchure : https://github.com/dcolthorp/matchure
match : https://github.com/swannodette/match
Yes, a system such as you describe now exists on Clojure! It is none other than Gerry Sussman's companion system to his -and Wisdom's- SICM (Structure and Interpretation of Classical Mechanics) book. For Clojure it's been named sicmutils, and ported by Colin Smith.
I've described it briefly elsewhere - https://stackoverflow.com/a/41646455/4070712 - but in short yes, it definitely does the four things you F# article mentions, viz.
Differentiation:
Simplification of algebraic expressions
Formatting
Parsing of expressions
and much, much more...
1) Differentiation (full partial differentiation supported)
> (defn ff [x y] (* (expt x 3)(expt y 5)))
> ((D ff) 'x 'y) ==> (down (* 3 (expt x 2) (expt y 5)) (* 5 (expt x 3) (expt y 4)))
> ;; i.e. vector of results wrt to both variables
NB. Two types of vectors are supported, "up" and "down" to accomodate covariant and contravariant expressions
2) Simplification of expressions: Oh, yes...
> (def unity (+ (square sin) (square cos)))
> (unity 'x) ==> 1 ;; yes we can deal with symbols
3) Formatting: Expressions can be rendered in TeX for beautiful display.
I can't show this easily here, but currently a Maple-style notebook/workshhet is under development, using Clojure's "Gorilla"
4) Parsing: Obviously. Converting between expressions and functions is a core part of the system.
Have a look at https://github.com/littleredcomputer/sicmutils . you don't even need Clojure to run it, you can use the supplied Java jar file.

Resources