In Mathematica, what does ### mean? - wolfram-mathematica

I've been working through problems on Project Euler, and some of the solutions that other people have posted use a triple-at-sign, i.e. '###'. In the help browser for v7, I find an entry for ## (which says it's the infix version of 'Apply') but none for ###. What does it mean?
EDIT: Here's an example, which I think I can post without violating the spirit of Project Euler:
bloc[n_, f_][t_] := {f ### #, #~Tr~f} & /# Join ## Partition[t, {n, n}, 1];

As others have noted, ### is, technically, shorthand for Apply with an optional third argument, as is explained deep in the documentation for Apply.
But I like to think of
f ### {{a,b}, {c,d}, {e,i}}
as shorthand for
f ###& /# {{a,b} {c,d}, {e,i}}
In other words, take a pure function (shorthand: ...#...&) that does an Apply (shorthand: ##) to a list of arguments, and Map (shorthand: /#) that over a list of such lists of arguments.
The result is
{f[a,b], f[c,d], f[e,i]}

### is the short form for Apply at level 1.
f ### {{a, b, c}, {d, e}}
is equivalent to
Apply[f, {{a, b, c}, {d, e}}, {1}]
Reference: http://reference.wolfram.com/mathematica/ref/Apply.html
You may need to expand the Scope and Level Specification sections.

f ### expr is equivalent to Apply[f, expr, {1}].
documents.wolfram.com

Related

SymbolName applied to a list of variables, some of which may have values assigned

In Mathematica:
I would like to pass a variable number of arguments to a function.
I would like to print the name of each argument. The problem is that SymbolName evaluates its input. For a given variable, you can get around this:
a=18;
SymbolName[Unevaluated[a]]
works. But that won't work if the variable is in a list. For example:
printname[x__]:=Print[Table[SymbolName[Unevaluated[{x}[[i]]]],{i,1,Length[{x}]}]];
printname[a,b,c]
will not work. Any suggestions?
Thanks in advance.
Mathematica tries to evaluate the argument of Unevaluated[] when you call it. So {x}[[i]] gets converted into {18, b, c}[[i]] which you didn't want and then the iteration over i doesn't work anymore because Unevaluated[] doesn't let the Table access the iterator.
So, to really solve the issue you should disable Mathematica's evaluation completely for the functions that you want to pass the symbols through.
In[1]:= SetAttributes[SymbolName, HoldAll];
SetAttributes[Map, HoldAll];
After this you can just do
In[2]:= a=18; SymbolName ### Unevaluated /# {a, b, c}
Out[2]:= {a, b, c}
where ### and /# are shorthand for Apply[] and Map[].
Setting Hold[] or similar attributes in Mathematica's built in functions can lead to trouble. See this question and answer in the Mathematica stackexchange for more information.
Specifically, to make a function that takes an arbitrary number of arguments would be
sym = SymbolName ### Unevaluated /# {##} &
But the List[] function that takes the sequence of arguments ## for the function & will again evaluate a and turning HoldAll on for List[] is not OK.
Thus the easiest way to do this is to define a function with HoldAll that just passes the args into a Block[] as the list of local variables. This makes a creates an isolated context where the variables do not evaluate to anything.
In[1]:= SetAttributes[f, HoldFirst];
In[2]:= f[seq__] := Block[{seq}, Print[SymbolName /# {seq}]];
In[3]:= a=18; f[a, b, c]
Out[3]:= {a, b, c}

How to remove the extra {} when Mapping a function to a list

Simple question, given a list like this
Clear[a, b, c, d, e, f];
lst = {{a, b}, {c, d}, {e, f}};
and suppose I have a function defined like this:
foo[x_,y_]:=Module[{},...]
And I want to apply this function to the list, so If I type
Map[foo, lst]
This gives
{foo[{a, b}], foo[{c, d}], foo[{e, f}]}
I want it to come out as
{foo[a, b], foo[c, d], foo[e, f]}
so it works.
What is the best way to do this? Assume I can't modify the function foo[] definition (say it is build-in)
Only 2 ways I know now are
Map[foo[#[[1]], #[[2]]] &, lst]
{foo[a, b], foo[c, d], foo[e, f]}
(too much work), or
MapThread[foo, Transpose[lst]]
{foo[a, b], foo[c, d], foo[e, f]}
(less typing, but need to transpose first)
Question: Any other better ways to do the above? I looked at other Map and its friends, and I could not see a function to do it more directly than what I have.
You need Apply at Level 1 or its short form, ###
foo###lst
{foo[a, b], foo[c, d], foo[e, f]}
One possible way is to change head of each element of lst from List to foo:
foo ## # & /# lst
{foo[a, b], foo[c, d], foo[e, f]}
Just to report puzzling performance tests of the both methods (###, ## # & /#) :
T = RandomReal[{1,100}, {1000000, 2}];
H[F_Symbol, T_List] :=
First#AbsoluteTiming[F ### T;]/First#AbsoluteTiming[F ## # & /# T;]
Table[{ToString[F], H[F, T]}, {F, {Plus, Subtract, Times, Divide, Power, Log}}]
Out[3]= {{"Plus", 4.174757},
{"Subtract", 0.2596154},
{"Times", 3.928230},
{"Divide", 0.2674164},
{"Power", 0.3148629},
{"Log", 0.2986936}}
These results are not random, but roughly proportional for very different data sizes.
### is roughly 3-4 times faster for Subtract, Divide, Power, Log while ## # & /# is 4 times faster for Plus and Times giving rise to another questions, which (as one can believe) could be slightly
clarified by the following evaluation:
Attributes#{Plus, Subtract, Times, Divide, Power, Log}
Only Plus and Times have attributes Flat and Orderless, while among the rest only Power (which seems relatively the most efficient there) has also an attribute OneIdentity.
Edit
A reliable explanation to observed performance boosts (thanks to Leonid Shifrin's remarks) should go along a different route.
By default there is MapCompileLength -> 100 as we can check evaluating SystemOptions["CompileOptions"].
To reset autocompilation of Map we can evaluate :
SetSystemOptions["CompileOptions" -> "MapCompileLength" -> Infinity]
Now we can test relative performance of the both methods by evaluating once more our H - performance testing function on related symbols and list :
Table[{ToString[F], H[F, T]}, {F, {Plus, Subtract, Times, Divide, Power, Log}}]
Out[15]= {{"Plus", 0.2898246},
{"Subtract", 0.2979452},
{"Times", 0.2721893},
{"Divide", 0.3078512},
{"Power", 0.3321622},
{"Log", 0.3258972}}
Having these result we can conclude that in general Yoda's approach (###) is the most efficient, while that provided by Andrei is better in case of Plus and Times due to automatic compilation of Map allowing better performance of (## # & /#).
A few more possibilities to pick from:
This one is a more verbose version of yoda's answer. It applies foo at level 1 of the list lst only (replaces the head List with the head foo):
Apply[foo, lst, {1}]
This does the same, but maps Apply over the list lst (essentially Andrei's answer):
Map[Apply[foo, #] &, lst ]
And this just replaces the pattern List[x__] with foo[x] at level 1:
Replace[lst, List[x__] -> foo[x], 1]
The answers on Apply[] are spot on, and is the right thing to do, but what you were trying to do, was to replace a List[] head with a Sequence[] head, i.e. List[List[3,5],List[6,7]] should become List[Sequence[3,5],Sequence[6,7]].
Sequence head is what naturally remains if a head of any list of parameters is deleted, so Delete[Plus[3,5],0] and Delete[{3,5},0] and Delete[List[3,5],0] would all produce Sequence[3,5].
So foo#Delete[#,0]&/#{{a, b}, {c, d}, {e, f}} will give you the same as foo###{{a, b}, {c, d}, {e, f}}.
Alternatively, foo[#/.List->Sequence]&/#{{a, b}, {c, d}, {e, f}} does the same thing.

Mathematica - selectively gathering nodes in a tree

I have a tree (expression) on which I want to gather only certain types of nodes - those that follow a certain pattern. I have a simplified example below:
A = {{{{},{0.3,0.3}},{0.2,0.2}},{0.1,0.1}};
TreeForm[A, PlotRangePadding->0]
Cases[A, {x_Real, y_Real}, Infinity]
The output:
Is this a good way to do it?
If instead of {x_, y_}, if I wanted to look for {{x1_, y1_}, {x2_, y_2}}, how can I exclude expressions like {x_, y_}, which also match?
Regards
EDIT (14/07/2011)
I have found that using a head other than List will greatly aid in finding such sub-expressions without collisions.
For example, reformulating the above:
A = {{{{}, pt[0.3, 0.3]}, pt[0.2, 0.2]}, pt[0.1, 0.1]};
List ### Cases[A, _pt, Infinity]
Output:
{{0.3,0.3},{0.2,0.2},{0.1,0.1}}
About the second part of your question, ie, selecting {{a,b},{c,d}}, how about
b = {{{{}, {0.3, 0.3}}, {0.2, 0.2}}, {{0.1, 0.1}, {0.3, 0.4}}};
TreeForm[b]
Cases[b, {{a_, b_}, {c_, d_}} /; (And ## NumericQ /# {a, b, c, d}), Infinity]
(so that they do not have to be Real but any Numeric will do)?
Here is an alternative to the form acl used, that I find more readable.
b = {{{{}, {0.3, 0.3}}, {0.2, 0.2}}, {{0.1, 0.1}, {0.3, 0.4}}};
With[{p = _?NumericQ}, Cases[b, {{p, p}, {p, p}}, -1] ]

List/matrix of coefficients equation (system of equations)

I try to extract coefficient from equations (system of equations) into list (matrix). I have tried CoefficientList[poly, {var1, var2, ...}] but without success.
This simple example should explain my problem:
Eq1 = a D[U[x1, x2], {x1, 2}] + b D[V[x1, x2], {x2, 2}]
Any advice?
Edit:
Daniel's Lichtblau solution is very clear (thanks you), but what if the equation that looks like this?
Eq1 = a D[U[x1, x2], {x1, 2}] + b D[V[x1, x2], {x2, 2}] + c W[x1, x2]
A simple example can be resolved as follows:
Is there any more elegant solution? (particularly for more complex expressions)
Ps I can't understand why, but this solution gives me the correct result.
Firstly the partial derivatives are represented with Derivative, so the pattern needs to match that. Also, I don't think you want to use CoefficientList as that would accept terms where both your expressions appear. All in all, the following should work:
In[7]:= (Coefficient[Eq1, #] &) /# {Derivative[2, 0][U][x1, x2], Derivative[0, 2][V][x1, x2]}
Out[7]= {a, b}
Here (Coefficient[Eq1, #] &) is an anonymous function that finds the coefficient of the argument, and /# maps it to the list on the right.
HTH
CoefficientArrays is often useful for extracting coefficients to linear systems in some set of variables. In this case we first need to get the list of variables.
dvars = Cases[Eq1, Derivative[__][_][__], -1];
CoefficientArrays returns a result of the form {constants, coefficients}. it uses sparse arrays so I'll convert to explicit lists with Normal.
Normal[CoefficientArrays[Eq1, dvars]]
Out[672]= {0, {b, a}}
Daniel Lichtblau
Wolfram Research

How should I write a function to be used in Apply in Mathematica?

I am wondering how I can write a function to be used in the Apply function in Mathematica? For example, I want to trivially re-implement the Or function, I found the following
Apply[(#1 || #2)&,{a,b,c}]
is not okay since it only Or'ed the first two elements in the list. Many thanks!
This will work, no matter how many vars, and is a general pattern:
Or[##]&,
for example
In[5]:= Or[##] & ## {a, b, c}
Out[5]= a || b || c
However, in the case of Or, this is not good enough, since Or is HoldAll and short-circuiting - that is, it stops upon first True statement, and keeps the rest unevaluated. Example:
In[6]:= Or[True, Print["*"]]
Out[6]= True
In[7]:= Or[##] & ## Hold[True, Print["*"]]
During evaluation of In[7]:= *
Out[7]= True
This will be ok though:
Function[Null,Or[##],HoldAll],
for example,
In[8]:= Function[Null, Or[##], HoldAll] ## Hold[True, Print["*"]]
Out[8]= True
and can be used in such cases (when you don't want your arguments to evaluate). Note that this uses an undocumented form of Function. The mention of this form can be found in the book of R.Maeder, "Programming in Mathematica".
HTH
Or ## {a, b, c}
Equivalent
Apply[Or, {a, b, c}]
Equivalent
{a, b, c} /. {x_, y__} -> Or[x, y]
Apply works like this:
{2 #1, 3 #2, 4 #3} & ## {a, b, c}
{2 a, 3 b, 4 c}
Plus[2 #1, 3 #2, 4 #3] & ## {a, b, c}
2 a + 3 b + 4 c
Are you sure you are expecting the right thing from Apply? If you look in the documentation, http://reference.wolfram.com/mathematica/ref/Apply.html, you will see that Apply[f,expr] simply replaces the head of f by expr. It does not, in general, give f[expr].
If you wish to operate with function f onto expr, try f#expr or f[expr].
Perhaps you understand the above and your question really is, "how do I define some f that, when I do Apply[f,{a,b,c}], does the same job as Or[a,b,c]. Is that it?

Resources