From: ············@gmail.com
Subject: Debugging lisp?
Date: 
Message-ID: <1109746140.105758.244730@l41g2000cwc.googlegroups.com>
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.

From: Peter Seibel
Subject: Re: Debugging lisp?
Date: 
Message-ID: <m3sm3etu21.fsf@gigamonkeys.com>
············@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
From: Christophe Rhodes
Subject: Re: Debugging lisp?
Date: 
Message-ID: <sq4qfu4ixp.fsf@cam.ac.uk>
············@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
From: Frank Buss
Subject: Re: Debugging lisp?
Date: 
Message-ID: <d0402t$7de$1@newsreader2.netcologne.de>
············@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
From: David Sletten
Subject: Re: Debugging lisp?
Date: 
Message-ID: <7BfVd.37432$xX3.19456@twister.socal.rr.com>
············@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
From: Andreas Eder
Subject: Re: Debugging lisp?
Date: 
Message-ID: <m3y8d6pf49.fsf@banff.eder.de>
············@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.
From: ············@gmail.com
Subject: Re: Debugging lisp?
Date: 
Message-ID: <1109797397.679171.195430@g14g2000cwa.googlegroups.com>
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.
From: William Bland
Subject: Re: Debugging lisp?
Date: 
Message-ID: <pan.2005.03.02.21.20.44.136506@abstractnonsense.com>
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.
From: Frank Buss
Subject: Re: Debugging lisp?
Date: 
Message-ID: <d05ce6$omg$1@newsreader2.netcologne.de>
············@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
From: David Steuber
Subject: Re: Debugging lisp?
Date: 
Message-ID: <87k6opk6ok.fsf@david-steuber.com>
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
From: Frank Buss
Subject: Re: Debugging lisp?
Date: 
Message-ID: <d05jko$9nq$1@newsreader2.netcologne.de>
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
From: Pascal Bourguignon
Subject: Re: Debugging lisp?
Date: 
Message-ID: <873bvdn3oc.fsf@thalassa.informatimago.com>
············@gmail.com writes:

> 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.

Well, the error was to not automatize the derivation. You could use
a preexisting library (for example. maxima), or just write  a
quick-and-dirty deriv function:

;;--------------------

(DEFUN NORMALIZE-/ (EXP)
  (UNLESS (CONSP EXP)
    (ERROR "INVALID FRACTION ~S." EXP))
  (CASE (LENGTH EXP)
    (0 (ERROR "INVALID FRACTION ~S." EXP))
    (1 (ERROR "INVALID FRACTION ~S." EXP))
    (2 `(/ 1 ,(SECOND EXP)))
    (3 EXP)
    (OTHERWISE (DO ((NUM   `(/ ,(SECOND EXP) ,(THIRD EXP)))
                    (REST  (CDDDR EXP) (CDR REST)))
                   ((NULL REST) NUM)
                 (SETQ NUM `(/ ,NUM ,(CAR REST)))))))


(DEFUN SIMPLIFY-STEP (EXP)
  (WHEN (CONSP EXP)
    (SETQ EXP (CONS (CAR EXP) (MAPCAR (FUNCTION SIMPLIFY) (CDR EXP)))))
  (COND
   ((ATOM EXP) EXP)
   ((AND (OR (EQ '* (CAR EXP)) (EQ '+ (CAR EXP))) (= 2 (LENGTH EXP)))
    (SECOND EXP))
   ((AND (EQ '* (CAR EXP))
         (SOME (LAMBDA (ITEM) (AND (NUMBERP ITEM) (= 0 ITEM))) (CDR EXP)))
    0)
   ((AND (EQ '* (CAR EXP))
         (SOME (LAMBDA (ITEM) (AND (NUMBERP ITEM) (= 1 ITEM))) (CDR EXP)))
    (CONS (CAR EXP) (REMOVE 1 (CDR EXP))))
   ((AND (EQ '- (CAR EXP))
         (= 3 (LENGTH EXP)) (TREE-EQUAL (SECOND EXP) (THIRD EXP)))
      0)
   ((EQ '+ (CAR EXP))
    (CONS (CAR EXP) (REMOVE 0 (CDR EXP))))
   (T
      EXP)))


(DEFUN SIMPLIFY (EXP)
  (DO ((SIM (SIMPLIFY-STEP EXP) (SIMPLIFY-STEP EXP)))
      ((TREE-EQUAL SIM EXP) SIM)
    (SETQ EXP SIM)))

   

(DEFUN DERIV-EXPR (EXP VAR)
  (COND 
   ((EQ EXP VAR) 1)
   ((ATOM EXP)   0)
   ((OR (EQ '+ (CAR EXP)) (EQ '- (CAR EXP)))
    (CONS (CAR EXP) (MAPCAR (LAMBDA (TERM) (DERIV-EXPR TERM VAR)) (CDR EXP))))
   ((EQ '* (CAR EXP))
    (COND ((= 2 (LENGTH EXP)) ;; (* x) == x
           (DERIV-EXPR (CADR EXP) VAR))
          (T ;; (f*g)' = (f'*g)+(f*g')
           `(+ (* ,(DERIV-EXPR (CADR EXP) VAR) ,@(CDDR EXP))
               (* ,(CADR EXP) ,(DERIV-EXPR (CONS '* (CDDR EXP)) VAR))))))
   ((EQ '/ (CAR EXP))
    (COND ((= 2 (LENGTH EXP)) ;; (/ x) == 1/x   ;; (1/f)' = -f'/f^2
           (/ (DERIV-EXPR (CADR EXP) VAR) (* EXP EXP)))
          ((= 3 (LENGTH EXP)) ;; (f/g)' = (f'g-g'f)/g^2
           `(/ (- (* ,(DERIV-EXPR (SECOND EXP) VAR) ,(THIRD EXP))
                  (* ,(SECOND EXP) ,(DERIV-EXPR (THIRD EXP) VAR)))
               (^ ,(THIRD EXP) 2)))
          (T (DERIV-EXPR (NORMALIZE-/ EXP) VAR))))
   ((EQ '^ (CAR EXP))
    (COND ((= 3 (LENGTH EXP)) ;; F^G
           `(* (+ (* ,(DERIV-EXPR (THIRD EXP) VAR) (LN ,(SECOND EXP)))
                  (/ (* ,(THIRD EXP) ,(DERIV-EXPR (SECOND EXP) VAR))
                     ,(SECOND EXP)))
               ,EXP))
          (ERROR "Invalid number of operand for ^.")))
   (T
    (ERROR "Unknown operator ~S."  EXP))))


#+clisp
(DEFUN SYMBOL-LAMBDA (FUN)
  (CONS 'LAMBDA (CDDAR (GET FUN 'SYSTEM::DEFINITION))))
;; try function-lambda-expression on other implementations,
;; but sometimes you get additionnal cruft in the lambda expression...


(DEFUN DERIV-FUNCTION (FUN)
  (COND
   ((SYMBOLP FUN)
    (DERIV-FUNCTION (symbol-lambda FUN)))
   ((LISTP FUN)
    (LIST 'LAMBDA (CADR FUN) 
      (SIMPLIFY (DERIV-EXPR (CADDR FUN) (CAADR FUN)))))
   (T (ERROR "Can't parse ~S." FUN))))

;;--------------------

(defun f (x) (+ (* x x x)  (* 3 x) 1))

(DERIV-FUNCTION 'F) ;; --> (LAMBDA (X) (+ (+ (* X X) (* X (+ X X))) 3))
;; simplify could be better and reduce it to (+ (* 3 x x) 3)
;; but for now we'll let the compiler do it...

(DEFMACRO DEF-DERIVATE (NAME FUN)
    `(DEFUN ,NAME ,@(CDR (DERIV-FUNCTION FUN))))

(DEF-DERIVATE DF/DX F)

(defun newx(x)	(- x (/ (f x) (df/dx x))))



-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
In deep sleep hear sound,
Cat vomit hairball somewhere.
Will find in morning.
From: Fred Gilham
Subject: Re: Debugging lisp?
Date: 
Message-ID: <u7psyhpw1i.fsf@snapdragon.csl.sri.com>
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