Several times recently I've made the same mistake:
(defun entropy (P &optional (K 2))
"Take a probability alist and a base, return the overall entropy."
(if (null P)
0
(+ (* (cdar P)
(- (log (cdar P) K)))
(entropy (cdr P)))))
instead of
(defun entropy (P &optional (K 2))
"Take a probability alist and a base, return the overall entropy."
(if (null P)
0
(+ (* (cdar P)
(- (log (cdar P) K)))
(entropy (cdr P) K))))
That is, forgetting to include the optional argument when recursing.
Is there an easy way to detect this error?
--
Trent Buck, Student Errant
For their next act, they'll no doubt be buying a firewall running under NT,
which makes about as much sense as building a prison out of meringue.
-- Tanuki
Instead of
(defun entropy (P &optional (K 2))
"Take a probability alist and a base, return the overall entropy."
(if (null P)
0
(+ (* (cdar P)
(- (log (cdar P) K)))
(entropy (cdr P) K))))
You could do something like the following:
(defun entropy (P &optional (K 2))
"Take a probability alist and a base, return the overall
entropy."
(labels ((entropy-1 (P K)
(if (null P)
0
(+ (* (cdar P)
(- (log (cdar P) K)))
(entropy-1 (cdr P) K)))))
(entropy-1 P K)))
At least then you will get a warning (i.e. with CMU Lisp) when you
forget the second argument in the recursive call.
--
Fred Gilham ······@csl.sri.com
The leading scholar who argued that millions starved during Stalin's
man-made famine was Robert Conquest of the Hoover Institution, often
described in the media as a right-wing think tank. When Mikhail
Gorbachev finally opened the official records in the last days of the
Soviet Union, it turned out that even more people had died during the
famine than Dr. Conquest had estimated. -- Thomas Sowell
Fred Gilham offered:
(defun entropy (P &optional (K 2))
"Take a probability alist and a base, return the overall
entropy."
(labels ((entropy-1 (P K)
(if (null P)
0
(+ (* (cdar P)
(- (log (cdar P) K)))
(entropy-1 (cdr P) K)))))
(entropy-1 P K)))
If you use labels, the inner function definition is within
the scope of the argument list, so you can exploit the fact
it is not changing thus:
(defun entropy (p &optional (base-of-logarithm 2))
(labels ((ent(p)
(if (endp p) 0
(+ (* (cdar p)
(log (cdar p) base-of-logarithm))
(ent (cdr p))))))
(- (ent p))))
Since we are only going to type it twice instead of three
times, we can afford to give it a more descriptive name :-)
Alan Crowe
Edinburgh
Scotland
On Sat, 26 Mar 2005 08:44:23 GMT, Trent Buck <·········@gmail.com>
wrote:
> (defun entropy (P &optional (K 2))
> "Take a probability alist and a base, return the overall entropy."
> (if (null P)
> 0
> (+ (* (cdar P)
> (- (log (cdar P) K)))
> (entropy (cdr P) K))))
To make it easier to read and easier to notice bugs, change it to
something like this:
(defun entropy (alist &optional (base 2))
"Take a probability alist and a base, return the overall entropy."
(loop as (s . p) in alist sum
(* p (- (log p base)))))
Spake David Smith:
> To make it easier to read and easier to notice bugs, change it to
> something like this:
>
> (defun entropy (alist &optional (base 2))
> "Take a probability alist and a base, return the overall entropy."
> (loop as (s . p) in alist sum
> (* p (- (log p base)))))
Intriguing. You've convinced me to learn LOOP.
--
Trent Buck, Student Errant
Hmm. Perhaps sometime next week I will go outside.
Trent Buck wrote:
>
> That is, forgetting to include the optional argument when recursing.
> Is there an easy way to detect this error?
>
You should probably deal with the faulty source of the problem. Tie
some electric paddles to your feet, and when you make an error....
:)
Another way would be to write a error checking function. That
will walk your source and flag potential errors like that. (functions
which call themsleves and have optional arguments. However this
a temporary problem, as there is still the faulty source of the
problem generating errors. (One note, all errors are not bad).
Wade
Wade Humeniuk <··················@telus.net> writes:
> Trent Buck wrote:
> > That is, forgetting to include the optional argument when recursing.
> > Is there an easy way to detect this error?
> >
>
> You should probably deal with the faulty source of the problem. Tie
> some electric paddles to your feet, and when you make an error....
>
> :)
>
> Another way would be to write a error checking function. That
> will walk your source and flag potential errors like that. (functions
> which call themsleves and have optional arguments. However this
> a temporary problem, as there is still the faulty source of the
> problem generating errors. (One note, all errors are not bad).
You'd need to add a declaration:
(declare (all-recursive-calls-must-include-optional-arguments k))
or:
(declare (all-calls-must-include-optional-arguments entropy k))
--
__Pascal Bourguignon__ http://www.informatimago.com/
Nobody can fix the economy. Nobody can be trusted with their finger
on the button. Nobody's perfect. VOTE FOR NOBODY.
Pascal Bourguignon wrote:
>
> You'd need to add a declaration:
>
> (declare (all-recursive-calls-must-include-optional-arguments k))
>
> or:
>
> (declare (all-calls-must-include-optional-arguments entropy k))
>
A more encompassing declaration would be in order
(declare (tolerate-programmer-stupidity -3))
Wade
Trent Buck <·········@gmail.com> writes:
> Several times recently I've made the same mistake:
>
> (defun entropy (P &optional (K 2))
> "Take a probability alist and a base, return the overall entropy."
> (if (null P)
> 0
> (+ (* (cdar P)
> (- (log (cdar P) K)))
> (entropy (cdr P)))))
>
> instead of
>
> (defun entropy (P &optional (K 2))
> "Take a probability alist and a base, return the overall entropy."
> (if (null P)
> 0
> (+ (* (cdar P)
> (- (log (cdar P) K)))
> (entropy (cdr P) K))))
>
> That is, forgetting to include the optional argument when recursing.
> Is there an easy way to detect this error?
Perhaps don't use an optional parameter?
(defvar *base* 2)
(defun entropy (P)
"Take a probability alist, return the overall entropy given the *base*."
(if (null P)
0
(+ (* (cdar P) (- (log (cdar P) *base*))) (entropy (cdr P)))))
(entropy p) ; with default *base*
(let ((*base* 3)) (entropy p)) ; with a different *base*
--
__Pascal Bourguignon__ http://www.informatimago.com/
Our enemies are innovative and resourceful, and so are we. They never
stop thinking about new ways to harm our country and our people, and
neither do we. -- Georges W. Bush
Spake Pascal Bourguignon:
> > (defun entropy (P &optional (K 2))
> > "Take a probability alist and a base, return the overall entropy."
> > (if (null P)
> > 0
> > (+ (* (cdar P)
> > (- (log (cdar P) K)))
> > (entropy (cdr P) K))))
> >
> > That is, forgetting to include the optional argument when recursing.
> > Is there an easy way to detect this error?
>
> Perhaps don't use an optional parameter?
Simply omitting &optional, even. Good idea.
> (defvar *base* 2)
>
> (defun entropy (P)
> "Take a probability alist, return the overall entropy given the *base*."
> (if (null P)
> 0
> (+ (* (cdar P) (- (log (cdar P) *base*))) (entropy (cdr P)))))
>
>
> (entropy p) ; with default *base*
> (let ((*base* 3)) (entropy p)) ; with a different *base*
--
Trent Buck, Student Errant
Hang on, this is no WENDIGO... It's some kind of HAPPY LOLLIPOP designed
by JAPANESE SCIENTISTS!
-- Bob the Angry Flower, Wendigo
Trent Buck seeks an insecticide for a particular kind of bug
Several times recently I've made the same mistake:
(defun entropy (P &optional (K 2))
"Take a probability alist and a base, return the overall entropy."
(if (null P)
0
(+ (* (cdar P)
(- (log (cdar P) K)))
(entropy (cdr P) ))))
^
|
`-- Whoops forgot the K
A general idea is to separate out the sequence-engine and
the code it is sequencing. For example
sequence-engine:
(defun expectation (discrete-probability-distribution
pointwise-function)
(loop for (item . prob) in discrete-probability-distribution
sum (* prob (funcall pointwise-function item prob))))
Build the application by providing a function to the sequence-engine:
(defun entropy (discrete-distribution
&optional (base-of-logarithm 2))
(- (expectation discrete-distribution
(lambda(i p)
(declare (ignore i))
(log p base-of-logarithm)))))
Alan Crowe
Edinburgh
Scotland