Re: Convert Products to Lists

*To*: mathgroup at christensen.cybernetics.net*Subject*: [mg1153] Re: Convert Products to Lists*From*: villegas (Robert Villegas)*Date*: Sat, 20 May 1995 00:43:19 -0400*Organization*: Wolfram Research, Inc.

bob at zim.uoregon.edu (Robert Zimmerman) writes: > Is it possible to convert a product of numbers to a list of numbers. > It can be done for symbols, > > > a b c //.Times->List > {a, b, c} > > but it doesn't work for numbers > > 2 4 6//.Times->List > 48 The //. operator (which is short for ReplaceRepeated) is like most functions: the arguments evaluate before the function takes effect. The command gets converted from ReplaceRepeated[2 4 6, Times -> List] to ReplaceRepeated[48, Times -> List] before it does any substitution. This is another example where wrapping Unevaluated around an argument can be useful. Unevaluated will make the structure Times[2, 4, 6] sit still while ReplaceRepeated performs substitutions on it. In[27]:= Unevaluated[2 4 6] /. Times -> List Out[27]= {2, 4, 6} Once you make Times[2, 4, 6] sit still, a lot of familiar expression manipulations become available: In[28]:= List @@ Unevaluated[2 4 6] Out[28]= {2, 4, 6} In[29]:= ReplacePart[Unevaluated[2 4 6], List, 0] Out[29]= {2, 4, 6} In[33]:= Level[Unevaluated[2 4 6], {1}] Out[33]= {2, 4, 6} Here are a couple operations different from yours taking place on Plus or Times objects. In comments after the inputs, I've written the command that is getting executed by the internal code as a result of Unevaluated forcing structures like Plus to be left alone. Extract explicit Integers, leaving out Symbols that happen to evaluate to Integers: In[34]:= {a, b} = {999, 777} Out[34]= {999, 777} In[35]:= Cases[Unevaluated[2 3 b 7 a], _Integer] (* Cases[Times[2, 3, b, 7, a], _Integer] *) Out[35]= {2, 3, 7} Distribute f over addition, just as if 1, 2, 3, 4 were symbols, because the addition is prevented. In[50]:= Distribute[Unevaluated @ f[1 + 2, 3 + 4] ] (* Distribute[f[ Plus[1, 2], Plus[3, 4] ]] *) Out[50]= f[1, 3] + f[1, 4] + f[2, 3] + f[2, 4] These are simple illustrations of what you can do, much along the lines of your original problem that needed to keep an arithmetic operation held. They're made up to illustrate the kinds of things you can do, and I think they show how unevaluated structures can be operated on. And I wouldn't be surprised if there are practical uses, although I can't think of any right this moment (you must have some, since you asked). But here is something which is more clearly in the practical vein for programming. What it does is pretty simple: it takes a sequence of instructions separated by ";" (a CompoundExpression) and inserts an instruction after each. The new instructions, which I'm thinking of as progress indicators, are in one-to-one correspondence with the main instructions, and would be input by a user, or possibly generated, wishing to test a program. Attributes[PrintProgress] = HoldAll PrintProgress[main_CompoundExpression, progress_CompoundExpression] := Inner[Sequence, Unevaluated[main], Unevaluated[progress], CompoundExpression] A test: In[6]:= Clear[a, b, c] In[7]:= PrintProgress[a = 1; b = 2; Abort[]; c = 3, Print[1]; Print[2]; Print[3]; Print[4] ] 1 2 Out[7]= $Aborted If you want the same progress command executed after each instruction, add a definition that inserts it after each instruction in the main program: PrintProgress[main_CompoundExpression, progress_] := Thread[Unevaluated[main ; progress], CompoundExpression] Just count the number of instructions that succeed: In[9]:= instructionCounter = 0 Out[9]= 0 In[10]:= PrintProgress[1 ; 2 ; 3 ; 4 ; Abort[] ; 5 ; 6, ++instructionCounter] Out[10]= $Aborted In[11]:= instructionCounter Out[11]= 4 Accumulate the values of MemoryInUse[] in a list so you can see how much memory the instructions are consuming: In[17]:= PrintProgress[MemoryUsage = {MemoryInUse[]}; Integrate[1/Sqrt[x^3 - 1], x]; Series[BesselK[5, z], {z, Infinity, 3}], AppendTo[MemoryUsage, MemoryInUse[]] ] Out[17]= {675548, 675580, 812676, 1265580} This can be done without Unevaluated, but I like Unevaluated because I don't have to worry about an extra level of Hold, which deepens the level of everything by one, and I don't have to ReleaseHold at the end, because once the structural operation is done, the result evaluates. Robby Villegas