Hard-coding limit results



Hi, another question somewhat related to the last.  Say I want to
define the entropy of a finite distribution.  The first, naive attempt
would be:

entropy(list) := -apply("+", map( lambda([a], a * log(a) ), list ));

Then it works fine for things such as:

(C7) entropy([1/2,1/4,1/4]);
				LOG(4)	 LOG(2)
(D7) 			        ------ + ------
				  2	   2

However, if I compute:

(C8) entropy([1/2,1/4,1/4,0]);
LOG(0) has been generated.
#0: LAMBDA([a],a*LOG(a))(a=0)(blobq.max line 0)
#1: entropy(list=[1/2,1/4,1/4,0])
 -- an error.  Quitting.  To debug this try DEBUGMODE(TRUE);)

This happens, as stated, precisely because log(0) is undefined, and
rightly so.  However, one typically wants to not worry about this in
this situation, since:

(C9) limit( p * log(p), p, 0);
(D9) 				       0

My question is really about how to handle the programming of this in
maxima.  Two approaches are:

entropy2(list) := apply("+", map( lambda([a], if a=0 then 0 else a*log(a)), list));

then:

(C12) entropy2([1/2,1/4,1/4,0]);
				 LOG(4)	  LOG(2)
(D12) 			       - ------ - ------
				   2	    2

but, for reasons discussed earlier, there are snarls:

(C14) entropy([p,1-p]), p=0;
LOG(0) has been generated.
#0: LAMBDA([a],a*LOG(a))(a=0)(blobq.max line 0)
#1: entropy(list=[0,1])
 -- an error.  Quitting.  To debug this try DEBUGMODE(TRUE);)

The second idea is:

limEntropy(list) := - apply("+", map( lambda([a], limit(x*log(x),x,a)), list));

this behaves nicely in the sense that

(C17) limEntropy([p,1-p]), p=1;
(D17) 				       0

however it's not really an ideal solution since, if I do:

(C26) limEntropy([p,1-p]);
(D26) 		    - p LOG(p) + LOG(1 - p) p - LOG(1 - p)
(C27) d24, p=0;
LOG(0) has been generated.
 -- an error.  Quitting.  To debug this try DEBUGMODE(TRUE);)

Maybe the problem for this last snarl is the behavior:

(C31) limit( p*log(p), p, x );
(D31) 				   x LOG(x)

What I'm naively wondering is this: how are things like the built-in
log handled?  Could I define a function mylog which had a rewrite rule
that mylog(0) => 0, for instance?

Symbolic ifs could handle this, but is there another approach?  A
customary way in maxima?  I feel somewhat like I'm beating around the
bush...

Thanks,
  Carl