Cordic Program, troubles

Discussion of Common Lisp
Post Reply
harrym
Posts: 4
Joined: Sun Dec 04, 2011 1:09 pm

Cordic Program, troubles

Post by harrym » Sun Dec 04, 2011 1:15 pm

Hello everyone,
I am a CLISP newbie, I am learning it in order to "learn better" my calculator's programming language (an HP50g, it uses UserRPL).
I am having trouble with my first program, a CORDIC routine used to calculate sine and cosine in computer with little calculation power. Here is the source:

Code: Select all

(setq vec (vector 45. 26.5650511771 14.0362434679 7.1250163489 3.576334375 1.78991060825 .895173710211 .447614170861 .223810500369 .111905677066 5.59528918938E-2 .027976452617 1.39882271423E-2 6.99411367535E-3 3.4970568507E-3 1.74852842698E-3 8.74264213694E-4 4.37132106872E-4 2.18566053439E-4 1.0928302672E-4 5.46415133601E-5 2.732075668E-5 1.36603783401E-5 6.83018917003E-6))

(format t "~% ~%Inserisci l'angolo: ")

(setq ang (read))

(setq c0 0.607252935)
(setq z0 ang)
(setq d 1)
(setq s0 0)

(loop as i below 23
do (cond 
	((> z0 0) (setq z1 (- z0 (svref vec i))) (setq c1 (- c0 * d s0)) (setq s1 (+ s0 * d c0))) 
	((< z0 0) (setq z1 (+ z0 (svref vec i))) (setq c1 (+ c0 * d s0)) (setq s1 (- s0 * d c0)))
	)
(setq z0 z1) 
(setq c0 c1) 
(setq s0 s1) 
(setq d (/ d 2))
)

(format t "~%Il seno dell'angolo inserito vale ~F° ~%" s0)
(format t "Il coseno dell'angolo inserito vale ~F° ~%" c0)
(format t "~% ~% ~%")
When I "run" the program the compiler says: *** - >: ANG is not a real number

I cannot work out this error, can anyone help me?
Thanks in advance,

harryme

smithzv
Posts: 94
Joined: Wed Jul 23, 2008 11:36 am

Re: Cordic Program, troubles

Post by smithzv » Sun Dec 04, 2011 10:00 pm

Hmmm... is it really true that learning Lisp will help with RPL programming? Maybe learning Forth, but Lisp?

Anyway, to get you started, the error you are getting, ">: ANG is not a real number", is using "real" in the mathematic sense. It means that the data that symbol ANG contains is either complex, or not a number at all. It needs to be real because complex numbers (and of course anything that is not a number) cannot be greater than or less than something else; basic complex math. So the error is coming from the form (> z0 0).

You can find this out for yourself by using the CLISP debugger. The first hint is that CLISP actually already gave you the function where the error occurred. The beginning of the error message >: may look like an angry face, but it is saying that the error occurred in function ">" and then giving the actual error message. You might read up about the CLISP debugger in the implementation notes but most of the time your tools are backtraces, break points (this is done by inserting the BREAK form in your code) and inspecting the data from the debugger, and single stepping. In this case, single stepping would have been the most use since you didn't know where the error happened.

You may need to clarify what you mean by "run" if you need further help. For instance, ANG is not a real number is a quite likely error since ANG is read from the user. What did you input for ANG? I suspect that you invoking this from a command line, in which case it might be a good time to wrap it up in a single function and call it from the CLISP REPL where most people write their code to be run from. Once you have that working, you can make it invokable from the command line if you still desire.

Konfusius
Posts: 62
Joined: Fri Jun 10, 2011 6:38 am

Re: Cordic Program, troubles

Post by Konfusius » Mon Dec 05, 2011 9:03 am

I cannot see an error in the program. Maybe the error message means ":ANG is not a real number". This could mean that you have mistakenly put a colon in front of ang somewhere else.

harrym
Posts: 4
Joined: Sun Dec 04, 2011 1:09 pm

Re: Cordic Program, troubles

Post by harrym » Mon Dec 05, 2011 10:00 am

smithzv wrote:Hmmm... is it really true that learning Lisp will help with RPL programming? Maybe learning Forth, but Lisp?

Anyway, to get you started, the error you are getting, ">: ANG is not a real number", is using "real" in the mathematic sense. It means that the data that symbol ANG contains is either complex, or not a number at all. It needs to be real because complex numbers (and of course anything that is not a number) cannot be greater than or less than something else; basic complex math. So the error is coming from the form (> z0 0).
Well, UserRPL is really similar to LISP, even though it uses RPN.
I thought the same thing, maybe the interpreter (is the right word) considered my input as a string, instead of a real number. But take a look at this program I wrote before the one I posted:

Code: Select all

    
(setq vec (vector 45. 26.5650511771 14.0362434679 7.1250163489 3.576334375 1.78991060825 .895173710211 .447614170861 .223810500369 .111905677066 5.59528918938E-2 .027976452617 1.39882271423E-2 6.99411367535E-3 3.4970568507E-3 1.74852842698E-3 8.74264213694E-4 4.37132106872E-4 2.18566053439E-4 1.0928302672E-4 5.46415133601E-5 2.732075668E-5 1.36603783401E-5 6.83018917003E-6 3.41509458501E-6))
    (format t "~% ~%Inserisci l'angolo da cercare: ")
    (setq ang (read))
    (setq calc 0)
    (loop as i below 24
    do (cond
        ((> (- ang calc) 0) (setq calc (+ calc (svref vec i))))
        ((< (- ang calc) 0) (setq calc (- calc (svref vec i))))
        )
    )
    (format t "L'angolo calcolato vale ~F° ~%" calc)
    (format t "La differenza tra i due angoli vale ~F°" (abs (- calc ang)))
    (format t "~% ~% ~%")
It is more or less the same, and there are no problems. Is there a funtion that can force the interpreter to consider real an input?
You may need to clarify what you mean by "run" if you need further help. For instance, ANG is not a real number is a quite likely error since ANG is read from the user. What did you input for ANG? I suspect that you invoking this from a command line, in which case it might be a good time to wrap it up in a single function and call it from the CLISP REPL where most people write their code to be run from. Once you have that working, you can make it invokable from the command line if you still desire.
I always insert 30 as input, so i can see if the program is correct (the output should be more or less 0.5).
The program is saved in a .lisp file, and then on the terminal I write clisp myfile.lisp. Then I write the number and hit return (well, I would do these stuff, the error break the program before letting me do this).
By the way, the error is right in the line you said.
I cannot see an error in the program. Maybe the error message means ":ANG is not a real number". This could mean that you have mistakenly put a colon in front of ang somewhere else.
I can't either, the program is only the piece of code I posted. No colon anywhere :(

harrym

smithzv
Posts: 94
Joined: Wed Jul 23, 2008 11:36 am

Re: Cordic Program, troubles

Post by smithzv » Mon Dec 05, 2011 12:02 pm

Okay, found your error. You appear to have tried to use infix notation. As it stands I'm not sure what you want to do, but you can't do "(- c0 * d s0)":
harrym wrote:

Code: Select all

...
(loop as i below 23
do (cond
   ((> z0 0) (setq z1 (- z0 (svref vec i)))
    ;; This isn't right
    (setq c1 (- c0 * d s0))
    (setq s1 (+ s0 * d c0)))
   ((< z0 0) (setq z1 (+ z0 (svref vec i))) (setq c1 (+ c0 * d s0)) (setq s1 (- s0 * d c0)))
   )
...
This is a tricky error as the symbol * has a meaning and it's value changes with every command you type in, which means that every time you run it, it might have a different result.

harrym
Posts: 4
Joined: Sun Dec 04, 2011 1:09 pm

Re: Cordic Program, troubles

Post by harrym » Mon Dec 05, 2011 1:31 pm

Yes, if I take out those two lines, the error disappears... but I have no idea how to solve my error :(
What I want to do is this:

Code: Select all

if(z0>0){
c1 = c0-d*s0;
s1 = s0+d*c0;
}
if(z0<0){
c1 = c0+d*s0;
s1 = s0-d*c0;
}
How could I solve?

harrym

smithzv
Posts: 94
Joined: Wed Jul 23, 2008 11:36 am

Re: Cordic Program, troubles

Post by smithzv » Mon Dec 05, 2011 2:36 pm

Oh, I see, you are using prefix, the only thing is that CL is fully parenthesized. That means "* a b" needs to be written as (* a b). This is actually a departure from RPN where every function is of fixed airity. So, whereas you might do something like " 3 4 5 * * " in RPN to get 60 (disclaimer: I have never owned an RPN calculator), in Lisp you could use (* 3 4 5) or (*3 (* 4 5)) but there have to be parentheses to mark the function call and the end of the arguments. I would translate your code to:

Code: Select all

(cond ((> z0 0)
       (setf c1 (- c0 (* d s0)))
       (setf s1 (+ s0 (* d c0))))
      ((< z0 0)
       (setf c1 (+ c0 (* d s0)))
       (setf s1 (- s0 (* d c0)))))

harrym
Posts: 4
Joined: Sun Dec 04, 2011 1:09 pm

Re: Cordic Program, troubles

Post by harrym » Wed Dec 07, 2011 2:25 am

Wow thank you, now it works perfectly :lol: I did not know that details, now I will print it in my mind :)
Thanks to everyone!

Post Reply