Preserving variable names in Mathematica - wolfram-mathematica

in Mathematica, i am trying to manipulate a list such that i can start with something like:
myList = List[{a,b,c,d}];
a=12;
b=15;
c=7;
d=9;
I would then like to be able to reorder the list with the output being the variable names instead of numbers.

As said by #george in comment, one of the simplest way to do what you want
is to use transformation rules. They allow to substitute a value for
a symbol, without assigning a value to that symbol. For instance in your case
(I have mangled the order because it is not relevant here):
myValues = {d->9, a->12, b->15, c->7}
Transformation rules have two arguments and you can extract them. So here is a way to get the list of symbols from a list of transformation rules. The Sort is here to have the symbols in the alphabetical order.
myList = Sort[Map[First, myValues]]
{a, b, c, d}
To get a list of values, just apply the transformation rules to a list of symbol
with the /. operator
myList /. myValues
{12, 15, 7, 9}
Now we know how to do that, we can sort the symbol according to their numerical value
mySortedList = myList[[Ordering[ myList /. myValues]]]
{c, d, a, b}
Ordering gives the position of elements in a list if they were sorted.
Here we use the list of numerical values and apply its order to the list of symbols.
As there is no OrderingBy command in Mathematica as far as I know, you can
also order the symbols by a given function by applying it inside Ordering this way :
myList[[Ordering[Map[EulerPhi, myList /. myValues]]]]
{a, c, d, b}
I hope it fits your application.
One thing one does very often in Mathematica is to keep the association between symbols and values in form of transformation rules and manipulate it.
In your case, it could take this form :
SortBy[ myValues, Last]
{c -> 7, d -> 9, a -> 12, b -> 15}
or
SortBy[myValues, EulerPhi[Last[#]] &]
{a -> 12, c -> 7, d -> 9, b -> 15}
Then you can choose to extract what you want. That's how graph information is manipulated.

myList = HoldForm[{a, b, c, d}];
a = 12;
b = 15;
c = 7;
d = 9;
Last /# Sort[{ReleaseHold[#], #} & /# Thread[myList]]
{c, d, a, b}

Related

How to get the names of symbols as a list of strings?

I can get the name of an individual symbol:
ts[s_]:=ToString[Unevaluated[s]];
SetAttributes[ts,HoldAll]
This seems to work
ss=5;
InputForm[ts[ss]]
gives
"ss"
Now I want to map this to a list of symbols, which does not work, because I cannot suppress the evaluation of ss:
InputForm[ts[#] & /# {aa, ss}]
gives
{"aa", "5"}
I'd appreciate any suggestions. Thank you very much.
ts[s_] := ToString[Unevaluated[s]]
SetAttributes[ts, HoldAll]
{a, b, c} = {1, 2, 3};
Map[ts, Unevaluated[{a, b, c}]]
{a, b, c}
You could also use ts[s_] := SymbolName[Unevaluated[s]]

how to generate list of products from elements of a pair of lists in mathematica

Is there a pre-canned operation that would take two lists, say
a = { 1, 2, 3 }
b = { 2, 4, 8 }
and produce, without using a for loop, a new list where corresponding elements in each pair of lists have been multiplied
{ a[1] b[1], a[2] b[2], a[3] b[3] }
I was thinking there probably exists something like Inner[Times, a, b, Plus], but returns a list instead of a sum.
a = {1, 2, 3}
b = {2, 4, 8}
Thread[Times[a, b]]
Or, since Times[] threads element-wise over lists, simply:
a b
Please note that the efficiency of the two solutions is not the same:
i = RandomInteger[ 10, {5 10^7} ];
{First[ Timing [i i]], First[ Timing[ Thread[ Times [i,i]]]]}
(*
-> {0.422, 1.235}
*)
Edit
The behavior of Times[] is due to the Listable attribute. Look at this:
SetAttributes[f,Listable];
f[{1,2,3},{3,4,5}]
(*
-> {f[1,3],f[2,4],f[3,5]}
*)
You can do this using Inner by using List as the last argument:
In[5]:= Inner[Times, a, b, List]
Out[5]= {2, 8, 24}
but as others already mentioned, Times works automatically. In general for things like Inner, it's frequently useful to test things with "dummy" functions to see what the structure is:
In[7]:= Inner[f, a, b, g]
Out[7]= g[f[1, 2], f[2, 4], f[3, 8]]
and then work backwards from that to determine what the actual functions should be to give the desired result.

Why does Extract add extra {} to the result and what is best way to remove them

When I type the following
lis = {1, 2};
pos = Position[lis, 1];
result = Extract[lis, pos]
the result is always a list.
{1}
another example
lis = {{1}, {2}};
pos = Position[lis, {1}];
result = Extract[lis, pos]
{{1}}
Mathematica always adds an extra {} in the result. What would be the best way to remove this extra {}, other than applying Flatten[result,1] each time? And is there a case where removing these extra {} can cause a problem?
You probably realise this, but Position and Extract return lists because the requested values may be found in more than one position. So in general, removing the outer brackets doesn't make sense.
If you are sure the result is a singleton list, using Flatten would destroy information if the element is itself a list. For example,
Position[{{1}},1]
gives a list whose sole element is a list. So in this case, using Extract would make more sense.
Even so, there are many situations where Mathematica treats {x} very differently to x, as in
Position[1,1]
Position[{1},1]
which have very different results. So whether you can remove the outer braces from a one-member list depends on what you plan to do with it.
If I understood your question correctly, you are asking why
lis = {{1}, {2}};
pos = Position[lis, {1}];
result = Extract[lis, pos]
returns
{{1}}
rather than
{1}
The answer is, I think, simple: Position[lis,{1}] gives the position at which {1}, not 1 appears in lis; when you then go and look at that position using Extract, you do indeed get {1} which is then wrapped in a list (which is exactly what happened in the first case, when you looked for 1 and obtained {1} as a result; just replace 1 by {1}, because that is now what you are asking for.
To see this more clearly, try
lis = {f[1], f[2]};
pos = Position[lis, f[1]];
result = Extract[lis, pos]
which gives
{f[1]}
The point here is that List in {1} (which is the same as List[1] if you check look at the FullForm) before was just a head, like f here. Should mathematica have remove f here? If not, then why should it have removed the innermost List earlier?
And finally, if you really want to remove the inner {} in your second example, try
lis = {{1}, {2, {1}}};
pos = Position[lis, {1}];
result = Extract[lis, pos, #[[1]] &]
giving
{1, 1}
EDIT: I am becoming puzzled with some of the answers here. If I do
lis = {{1}, {2, {1, 2, {1}}}};
pos = Position[lis, 1];
result = Extract[lis, pos]
then I get
{1, 1, 1}
in result. I only get the extra brackets when I actually obtain the positions of {1} in pos instead of the positions of 1 (and then when I look at those positions, I find {1}). Or am I missing something in your question?
Short answer: You should probably use First#Position[...]
Long answer:
Lets separate the question to 2 parts:
Why do you have the extra {} in the result for Position?
i.e. why:
lis = {1, 2};
Position[lis, 1]
returns {{1}}?
This is in order to work consistently with n-dimensional list, that may have the requested values in more than one position. For example:
lis = {{1, 2, 3}, {1, 5, 6}, {1, 2, 1}};
Position[lis, 1]
returns {{1, 1}, {2, 1}, {3, 1}, {3, 3}}
which is a list of the coordinates the result is found in.
So in your case:
lis = {1, 2};
Position[lis, 1]
return {{1}}, as in: we found your requested value one time, in the coordinate-set {1}.
Now, a lot of times Mathematica assume that there might be a list of solutions (for example, in Solve), but the user know that he expect only one. A suitable code to this in your case will be First#Position[...]. this will return the first (and, assumebly, only) element in the list of positions --
So, if you are sure that the element you are searching for exist only once in the list and want to know where, use this way.
Why do you have the extra {} in the result for Extract?
Extract can work in two different ways.
If I'm doing Extract[{{a, b, c}, {d, e, f}, {g, e, h}}, {1, 2}]
I will get b, so extract with a 1 dimensional list of is just choosing and returning this element. In fact, Extract[lis, {1, 2}] is equal to lis[[1, 2]]
If I'm doing Extract[{{a, b, c}, {d, e, f}, {g, e, h}}, {{1, 2}, {3, 4}}]
I will get {b, h}, so extract with a 2 dimensional list is choosing and returning a list of elements.
In your case(s), you are doing Extract[lis, {{1}}], as in: give me a list containing only the element lis[[1]]. The result is always this element in a list, which is the extra {}

repeat a function n times in Mathematica

I want to repeat a function n times on a table, For n=2 I have the following code, How can I be sure that the function had run twice since my fc is differend every time?
smat = Table[{9, 8, 10}, {3}]
f[x_?Table] := ReplacePart[
x, {{2, 1} -> x[[2]][[1]] - #, {2, 2} -> x[[2]][[2]] + #}] &# fc[x[[2]][[1]]];
fc[k_?NumericQ] := Count[RandomReal[{0, 1}, k], x_ /; x < .1]
Nest[f, smat, 2]
This is probably what you want:
smat = Table[{9, 8, 10}, {3}]
ClearAll[f, fc];
f[x_List] :=
ReplacePart[
x, {{2, 1} -> x[[2]][[1]] - #, {2, 2} -> x[[2]][[2]] + #}] &#
fc[x[[2]][[1]]];
fc[k_?NumericQ] := Count[RandomReal[{0, 1}, k], x_ /; x < .1]
Nest[f, smat, 2]
ClearAll clears any previous definitions for those symbols (just in case). f[x_?Table] won't work; you want f[x_List], which means that the argument has a List head (Table is not a Head, and ? isn't what you want here).
I am not sure I have really answered your question though...
EDIT: To be clear, f[x_?something] means "apply something to x and, if it returns True, evaluate the right hand side of the := that follows. Look up PatternTest in Mathematica's documentation for more.
Acl covered the problems with the code pretty well, so I won't. To answer your question, though, I'd first separate your functions f and fc in separate cells, with fc being declared prior to f, and preface each cell with Clear[<function name>]. Now, to test if f is being applied twice, temporarily replace fc with
fc[_]:= a
or use another "dummy" value other than a, but it should be symbolic to increase readability. As a point of note, {1,2,3} + a == {1 + a, 2 + a, 3 + a}, so if f is applied twice, each term in x[[2]][[1]] and x[[2]][[2]] will have 2 a added to it.
Now, if you are unsure if fc is working correctly by itself, I'd apply it to a number separate cases without f, first.

Diciness with extracting things from a Hold'd expression

Suppose I have a list of param->value rules where the params are symbols that might have values assigned to them. For example:
{a, b, c} = {1, 2, 3};
x = Hold[{a->1, b->2, c->3}];
I need the list wrapped in Hold otherwise it would evaluate to {1->1, 2->2, 3->3}. (I'm open to any alternatives to Hold there if it makes the rest of this easier.)
Now suppose I want to convert x into this:
{"a"->1, "b"->2, "c"->3}
The following function will do that:
f[h_] := Block[{a,b,c}, ToString[#[[1]]]->#[[2]]& /# ReleaseHold#h]
My question: Can you write a version of f where the list of symbols {a,b,c} doesn't have to be provided explicitly?
Here is a way using Unevaluated:
In[1]:= {a, b, c} = {1, 2, 3};
In[2]:= x = Hold[{a -> 1, b -> 2, c -> 3}];
In[3]:= ReleaseHold[
x /. (symb_ -> e_) :> ToString[Unevaluated[symb]] -> e]
Out[3]= {"a" -> 1, "b" -> 2, "c" -> 3}
{a, b, c} = {1, 2, 3};
x = Hold[{a -> 1, b -> 2, c -> 3}];
f[x_] := Cases[x, HoldPattern[z_ -> y_] :>
StringTake[ToString[(Hold#z)], {6, -2}] -> y, 2];
f[x] // InputForm
Out:
{"a" -> 1, "b" -> 2, "c" -> 3}
Perhaps not very elegant, but seems to work.
This is a bit of an old question, but I think there's an answer that combines the virtues of both Andrew Moylan's answer and belisarius' answer. You really want to have lists of rules with HoldPattern on the left-hand side, instead of lists of rules that have Hold wrapped around the whole thing, so that you can actually use the rules without having to go through any sort of ReleaseHold process.
In[1]:= {a, b, c} = {1, 2, 3};
Unevaluated can also be helpful in constructing the sort of list you want:
In[2]:= x = Thread[HoldPattern /# Unevaluated[{a, b, c}] -> Range[3]]
Out[2]= {HoldPattern[a] -> 1, HoldPattern[b] -> 2, HoldPattern[c] -> 3}
Now you can do what you want with rule replacement. It's a bit involved, but it's something I find myself doing over and over and over again. You may notice that this list of rules has almost exactly the form of a list of OwnValues or DownValues, so being able to manipulate it is very helpful. The trick is using HoldPattern and Verbatim in concert:
In[3]:= f[rules_] :=
Replace[rules,
HoldPattern[Verbatim[HoldPattern][s_Symbol] -> rhs_] :>
With[{string = ToString[Unevaluated[s]]},
string -> rhs], {1}]
The level spec on Replace is just there to make sure nothing unexpected happens if rhs is itself a rule or list of rules.
In[4]:= f[x] // InputForm
Out[4]= {"a" -> 1, "b" -> 2, "c" -> 3}

Resources