# Extension question on How to replace the value that include infinity?

Based on earlier question How to replace the value that include infinity?,

Now, If I have the input A

A= {-3, 0, 1,2}


and do the operation :

B = -Total[(#*Log2[#]& /@ A]


Hence, I do

If[# == 0, 0, # Log2[#]] & /@ A
hold = Hold[# Log2[#]] & /@ A
ReleaseHold[hold /. HoldPattern[0 Log2[0]] -> 0]


to replace 0.

Now, how can I not enter a negative number in the calculation in B. In other words, B only calculates the positive number and [0 Log2[0]] -> 0.

Thank you very much.

B = -Total[If[# > 0, (#*Log2[#]), 0] & /@ A]

• Thank you for the respond. It try it by puting the given expression in last line and i get {-((3*(I*Pi + Log[3]))/Log[2]), 0, 0, 2} and the answer is -2. the answers is correct, but I want to know, the output of negative value is just expression and not include in calculation right? Aug 5, 2016 at 13:45

For the kind of operation you appear to be doing I typically write a customized function to replace the built-in, here Log2. Basically:

Attributes[pLog2] = Listable;

pLog2[x_?NonPositive] := 0
pLog2[x_?NumericQ] := Log2[x]

Format[pLog2[x_]] := HoldForm @ Subscript[Log2, p][x]


Now:

#*pLog2[#] & /@ {-3, 0, 1, 2}

{0, 0, 0, 2}


And also:

#*pLog2[#] & @ {-3, 0, 1, 2, Pi, x}


I included the formatting rule just to illustrate what is possible.

• thank you very much for helping me. I already run it but how can I do if I want to substitute the list {-3,0,1,2} as A not the list.? Aug 5, 2016 at 13:56
• @munirah I may misunderstand but I think you mean simply A = {-3, 0, 1, 2} and then on another line -Total[#*pLog2[#] & @ A], or just -Total[A*pLog2[A]]. By the way it is best not to start user Symbol names (like A) with capital letters, as these may conflict with built-ins, e.g. C, D, E, I, N are all existing reserved Symbols. Aug 5, 2016 at 19:05
• It mean when I want to make any, it better for me use small letter?Here, I try to replace the symbol A instead the list {-3, 0, 1, 2} since the list can be variety. hence, I do like this : -Total[#*pLog2[#] & @ A] but iit come error Aug 7, 2016 at 0:32
• @munirah: in short, always use a instead of A, c instead of C, etc. as your variables. Aug 7, 2016 at 1:13

Here is my proposal:

ClearAll[xlgx];
xlgx[x_] := x * Log2[(1 - UnitStep[-x]) (x - 1) + 1];


Or adapting Mr.Wizard's approach, just "truncating" the logarithm:

ClearAll[pLog2];
pLog2[x_] := Log2[(1 - UnitStep[-x]) (x - 1) + 1];


Examples:

OP's:

-Total@xlgx[{-3, 0, 1, 2}]
(*  -2  *)


Vectorized:

xlgx[Range[-4, 4, 2]]
(*  {0, 0, 0, 2, 8}  *)


Preserves packed arrays (provided output is machine-sized):

xlgx[RandomReal[{-1, 1}, 1000]] // DeveloperPackedArrayQ
(*  True  *)

xlgx[2^Range[0, 57]] // DeveloperPackedArrayQ
(*  True  *)


Valid values:

input = RandomReal[{-1, 10}, 10000];
xlgx[input] == (# Log2[#] /. x_?(Not@*DeveloperMachineRealQ) :> 0. & /@ input)
(*  True  *)

• Thank you for sharing . i so new in mathematica. I will learn it slowly. It too complex to me to understand Aug 5, 2016 at 14:50
• @munirah Yeah, there is a lot to learn. Fortunately you can still do a lot even with a little knowledge. Try your best to learn on your own using resources like (18), but do not hesitate to ask Questions when you run into trouble. Aug 5, 2016 at 19:01
• thank you very much @Mr. Wizard. I learn a lot and improve from this forum. People inside here help me very much. From zero I learn and learn and will learn . Aug 7, 2016 at 0:27