I've only done one simple, barely more complicated than hello word,
lisp program before. So, I'm trying to use newton's method on an
equation at a certain point in an equation (this is not a homework
problem, I just decided to turn a matlab example into lisp). I cannot
for the life of me figure out what is wrong with this program. I'm
currently using clisp, and I can't seem to find a debugger for it
(something similar to python's pdb would be nice).
(defun f (x)
(+
(* x x x) (* 3 x) 1))
(defun dx(x)
(+ (* 3 x x) (* 3 x) 1))
(defun newx(x)
(- x (/ (f x) (dx x))))
(defun newtons-method (x num)
(if (not (if (not (= num 1)) (newtons-method (newx x) (- num 1) ) ))
(list x ) )
)
(print (newtons-method 0.0 15))
Now at the bottom level of the recursion the the inner if should return
nil, leading the program to return the current value of x. But it's
not. I know I'm missing something, and without a debugger, I can't
figure out what's wrong.
············@gmail.com writes:
> I've only done one simple, barely more complicated than hello word,
> lisp program before. So, I'm trying to use newton's method on an
> equation at a certain point in an equation (this is not a homework
> problem, I just decided to turn a matlab example into lisp). I
> cannot for the life of me figure out what is wrong with this
> program. I'm currently using clisp, and I can't seem to find a
> debugger for it (something similar to python's pdb would be nice).
>
> (defun f (x)
> (+
> (* x x x) (* 3 x) 1))
>
> (defun dx(x)
> (+ (* 3 x x) (* 3 x) 1))
>
> (defun newx(x)
> (- x (/ (f x) (dx x))))
>
>
>
> (defun newtons-method (x num)
> (if (not (if (not (= num 1)) (newtons-method (newx x) (- num 1) ) ))
> (list x ) )
>
> )
>
> (print (newtons-method 0.0 15))
>
>
> Now at the bottom level of the recursion the the inner if should
> return nil, leading the program to return the current value of x.
> But it's not. I know I'm missing something, and without a debugger,
> I can't figure out what's wrong.
There are various debugging tools built into Common Lisp. You can
insert calls to BREAK to drop into the debugger at any point. And
TRACE will allow you to trace specific function calls. And STEP lets
you step through execution. See a reference such as the HyperSpec for
the details. But be aware that the exact user interface (i.e. what
happens when you get dropped in the debugger, what output TRACE
generates, or what happens after you call STEP) will depend on the
implementation. But the operations themselves are standard.
-Peter
--
Peter Seibel ·····@gigamonkeys.com
Lisp is the red pill. -- John Fraser, comp.lang.lisp
············@gmail.com writes:
> Now at the bottom level of the recursion the the inner if should return
> nil, leading the program to return the current value of x. But it's
> not. I know I'm missing something, and without a debugger, I can't
> figure out what's wrong.
Peter's suggested some debugging tools that your implementation will
help you to solve your problem; evaluating (trace newtons-method) will
probably help you a little. I'll try to save you a little extra pain
by pointing out that you've probably mistranscribed dx: it doesn't
look like it's evaluating the derivative of f to me.
Christophe
············@gmail.com wrote:
> (defun f (x)
> (+
> (* x x x) (* 3 x) 1))
>
> (defun dx(x)
> (+ (* 3 x x) (* 3 x) 1))
>
> (defun newx(x)
> (- x (/ (f x) (dx x))))
your dx is wrong and you should format it more Lisp like:
(defun f (x)
(+ (* x x x)
(* 3 x)
1))
(defun dx (x)
(+ (* 3 x x)
3))
(defun new-x (x)
(- x
(/ (f x) (dx x))))
Try SLIME (http://common-lisp.net/project/slime/) with Emacs or some
trial version of commercial Lisp environments, they have auto indention.
> (defun newtons-method (x num)
> (if (not (if (not (= num 1)) (newtons-method (newx x) (- num 1)
> ) ))
> (list x ) )
>
> )
ok, first lets format it a bit better (your "(if (not" can be rewritten
as "unless", because you use only the "true" result)
(defun newtons-method (x num)
(unless (unless (= num 1)
(newtons-method (new-x x) (- num 1)))
(list x)))
and perhaps this code helps you, because it shows the problem:
(defun test (x)
(when (> 0 x) (test (1- x)))
x)
(test foo) -> foo
BTW: you don't need (list x), because you can just return the atom x.
> (print (newtons-method 0.0 15))
you don't need to use print, because as the REPL says: read-eval-print
loop, it prints automaticly.
If you want a solution, scroll down, but first try it by yourself, that's
the best way to learn a language.
(defun newtons-method (x num)
(if (/= num 1)
(newtons-method (new-x x) (1- num))
x))
--
Frank Bu�, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
············@gmail.com wrote:
> I've only done one simple, barely more complicated than hello word,
> lisp program before. So, I'm trying to use newton's method on an
> equation at a certain point in an equation (this is not a homework
> problem, I just decided to turn a matlab example into lisp). I cannot
> for the life of me figure out what is wrong with this program. I'm
> currently using clisp, and I can't seem to find a debugger for it
> (something similar to python's pdb would be nice).
>
> (defun f (x)
> (+
> (* x x x) (* 3 x) 1))
>
> (defun dx(x)
> (+ (* 3 x x) (* 3 x) 1))
>
> (defun newx(x)
> (- x (/ (f x) (dx x))))
>
>
>
> (defun newtons-method (x num)
> (if (not (if (not (= num 1)) (newtons-method (newx x) (- num 1) ) ))
> (list x ) )
>
> )
>
> (print (newtons-method 0.0 15))
>
>
> Now at the bottom level of the recursion the the inner if should return
> nil, leading the program to return the current value of x. But it's
> not. I know I'm missing something, and without a debugger, I can't
> figure out what's wrong.
>
In addition to what Peter and Christophe have already mentioned, I would
suggest that you start with a simpler case than NUM = 15. Use TRACE and
then try to understand why you get different results for even and odd
initial values of NUM (say 4 and 5).
Furthermore, your use of IF is very unusual. You might want to take a
look at COND instead:
http://www.lispworks.com/documentation/HyperSpec/Body/m_cond.htm
David Sletten
············@gmail.com writes:
> (defun f (x)
> (+
> (* x x x) (* 3 x) 1))
>
> (defun dx(x)
> (+ (* 3 x x) (* 3 x) 1))
>
I think your problem is with the definition of dx: (it is the
derivative isn't it?)
try: (defun dx (x) (+ (* 3 x x) 3))
That should do the trick.
'Andreas
--
Wherever I lay my .emacs, there's my $HOME.
Thanks to everyone who pointed out my derivative being wrong. I was up
past when I'm normally awake and I didn't spot it.
I got it working last night, I ended up using a loop, which I'm
guessing isn't a lispy thing to do.
Still trying to wrap my head around the language. The way of doing
things in lisp is radically different from all the imperative languages
I've used before. I do like it's simple basic syntax, however.
On Wed, 02 Mar 2005 13:03:17 -0800, brian.peyton wrote:
> I got it working last night, I ended up using a loop, which I'm
> guessing isn't a lispy thing to do.
On the contrary. Using a loop is a perfectly lispy thing to do. It's not
a schemey thing to do, but that's another matter.
Cheers,
Bill.
············@gmail.com wrote:
> Thanks to everyone who pointed out my derivative being wrong. I was up
> past when I'm normally awake and I didn't spot it.
>
> I got it working last night, I ended up using a loop, which I'm
> guessing isn't a lispy thing to do.
loop is fine. How does it look like? I hope something like this:
(defun newtons-method (x num)
(dotimes (i num x) (setf x (new-x x))))
--
Frank Bu�, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
Frank Buss <··@frank-buss.de> writes:
> loop is fine. How does it look like? I hope something like this:
>
> (defun newtons-method (x num)
> (dotimes (i num x) (setf x (new-x x))))
I've never liked dotimes when the var isn't used:
(defun newtons-method (x num)
(loop repeat num do
(setf x (new-x x))
finally (retun x)))
Although my form is a little more typing.
--
An ideal world is left as an excercise to the reader.
--- Paul Graham, On Lisp 8.1
David Steuber <·····@david-steuber.com> wrote:
> I've never liked dotimes when the var isn't used:
>
> (defun newtons-method (x num)
> (loop repeat num do
> (setf x (new-x x))
> finally (retun x)))
a shorter version:
(defun newtons-method (x num)
(loop repeat num do (setf x (new-x x))) x)
but your version is easier to understand and this is one of the main
advantages of Lisp: you can write and read it like pseudo-code.
Another idea would be to define a general function to evaluate forms like
xn+1=f(xn):
(defun iterate (&key x count fx)
(loop repeat count do
(setf x (funcall fx x))
finally (return x)))
then you can define newtons-method like this:
(defun newtons-method (x count)
(iterate :x x :count count :fx #'new-x))
some other examples:
(defun square (a count)
(iterate :x 1
:count count
:fx #'(lambda (y) (/ (+ y (/ a y)) 2))))
(square 81.0 5) -> 9.014272376994608
(defun power (base exp)
(iterate :x 1
:count exp
:fx #'(lambda (y) (* base y))))
(power 2 3) -> 8
--
Frank Bu�, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
Apart from the incorrect dx function, this function is your real
problem.
(defun newtons-method (x num)
(if (not (if (not (= num 1)) (newtons-method (newx x) (- num 1) ) ))
(list x ) )
)
You are trying to do a recursion. The standard way to do what you
want is something like the following:
(defun newtons-method (x num)
(if (zerop num)
(list x )
(newtons-method (newx x) (- num 1))))
Recursions always have a base case and a recursive case. The above is
a normal, idiomatic way to do recursions.
You can see that this would make it easier to do the "epsilon"
version:
(defvar *epsilon* .00001)
(defun newtons-method (x delta)
(if (< (abs delta) *epsilon*)
(list x )
(newtons-method (newx x) (- x (newx x)))))
Then you call it with something like
(newtons-method 0.0 1.0)
Of course then you want to eliminate the double call to newx:
(defun newtons-method (x delta)
(let ((new-x (newx x)))
(if (< (abs delta) *epsilon*)
(list x )
(newtons-method new-x (- x new-x)))))
Then you can get rid of the delta if you like:
(defun newtons-method (x)
(let ((new-x (newx x)))
(if (< (abs (- x new-x)) *epsilon*)
new-x
(newtons-method new-x))))
(I've also gotten rid of the (list ... ) around the return value,
which is unnecessary.)
--
Fred Gilham ······@csl.sri.com
A Bolshevik speaker promised his audience "come the revolution, we
will all eat strawberries and cream." "But I don't like strawberries
and cream," responded a listener. "Come the revolution we will *all*
eat strawberries and cream!," the Bolshevik intoned. -- Butler Shaffer