Related
My aim is to create a lot of functions f_i in a loop. These functions depend on parameters a[[i]], which can be taken from array A = {a1, a2, ...}. In order to eliminate the influence of the interator i, which leads to the situation when all functions are the same, I aspire to create variable names for each iteration.
The example: suppose I have got the array W = {1,2,3, ..., 100} and I should create variables w1 = 1, w2 = 2, ..., w100 = 100. I am trying to do this with the help of a for-loop:
loc[expr1_, expr2_] :=
ToExpression[StringJoin[ToString[expr1], ToString[expr2]]];
For[i = 1, i <= 100, i++,
{
loc[w, i] = W[[i]];
}]
When I need to see which value variable wk contains, then wk is not defined. But loc[w, k] = k is known.
How can I define variables wi? Or is there another way to create functions in a loop?
Thanks in advance
The way you are using {} leads me to believe that you have prior experience with other programming languages.
Mathematica is a very different language and some of what you know and expect will be wrong. Mathematica only uses {} to mean that is a list of elements. It is not used to group blocks of code. ; is more often used to group blocks of code.
Next, try
W={1,2,3};
For[i=i,i<=3,i++,
ToExpression["w"<>ToString[i]<>"="<>ToString[i]]
];
w2
and see that that returns
2
I understand that there is an intense desire in people who have been trained in other programming languages to use For to accomplish things. There are other ways o doing that for most purposes in Mathematica.
For one simple example
W={1,2,3};
Map[ToExpression["z"<>ToString[#]<>"="<>ToString[#]]&,W];
z2
returns
2
where I used z instead of w just to be certain that it wasn't showing me a prior cached value of w2
You can even do things like
W={1,2,3};
loc[n_,v_]:=ToExpression[ToString[n]<>ToString[v]<>"="<>ToString[v]];
Map[loc[a,#]&,W];
a3
which returns
3
Ordinarily, you will use indexed variables for this. E.g.,
ClearAll[x, xs]
n = 4
xs = Array[Indexed[x, #] &, 4]
Example use with random data:
RandomSeed[314]
mA = RandomInteger[{0, 99}, {n, n}]
vb = RandomInteger[{0, 99}, n]
Solve[mA.xs == vb, xs]
This is just for illustration; one would ordinarily use LinearSolve for the example problem. E.g., MapThread[Rule, {xs, LinearSolve[mA, vb]}].
It would be simpler to use a function variable, e.g. w[1], but here is a method to define w1 etc.
Note Clear can clear assignments using string versions of the symbols.
W = {1, 2, 7, 9};
Clear ## Map["w" <> ToString[#] &, W]
Map[(Evaluate[Symbol["w" <> ToString[#]]] = #) &, W];
w9
9
Symbol /# Map["w" <> ToString[#] &, W]
{1, 2, 7, 9}
Alternatively, with a function variable . . .
Map[(w[#] = #) &, W]
{1, 2, 7, 9}
w[9]
9
Also, using the OP's structure
Clear[loc]
Clear[w]
Clear ## Map["w" <> ToString[#] &, W]
W = {1, 2, 3, 4};
loc[expr1_, expr2_] := StringJoin[ToString[expr1], ToString[expr2]]
For[i = 1, i <= 4, i++, Evaluate[Symbol[loc[w, i]]] = W[[i]]]
Symbol /# Map["w" <> ToString[#] &, W]
{1, 2, 3, 4}
Note Evaluate[Symbol[loc[w, i]]] = W[[i]]] has the advantage that if the data at W[[i]] is a string it does not get transformed as it would by using ToExpression.
Best way to get the Dimension of a till now unknown symbol.
For example:
foo = Dimensions[undefined][[1,1]];
foo /.undefined -> {{1,2},{3,4}}
Theses lines of code do not work. Does anyone know, how to write this correctly?
I have to import the the values by substitutions. 'foo' as a function and 'a' as a parameter is unfortunately no alternative for me.
You have the right idea in your self-answer and I voted for it. However you should be aware that MatrixQ is not as general as you might want. For example a three dimensional tensor will fail it:
tensor = RandomInteger[9, {3, 2, 4}];
MatrixQ[tensor]
False
Dimensions can be used on an expression that is not even a List:
f[f[1, 2], f[3, 3]] // Dimensions
{2, 2}
Further your use of Part is not correct. Note the warning message:
dim[undefined][[1, 1]]
During evaluation of In[106]:= Part::partd: Part specification dim[undefined][[1,1]] is longer than depth of object. >>
dim[undefined][[1, 1]]
There is no part (1, 1) in the output of Dimensions. If you instead use [[1]] you will simply extract undefined from dim[undefined]. Instead you should include the part extraction in the definition of dim, or if you have Mathematica 10+ you can use Indexed.
I propose:
dims[x : _[__], part__: All] := Dimensions[x][[part]]
Now:
dims[undefined] /. undefined -> tensor
{3, 2, 4}
dims[undefined, 1] /. undefined -> tensor
3
dims[undefined, 2] /. undefined -> f[f[1, 2], f[3, 3]]
2
Visit the dedicated Mathematica Stack Exchange site:
I found a possibility:
Need to wrap 'Dimensions'
dim[x_?MatrixQ] := Dimensions[x];
...
foo = dim[undefined][[1,1]];
foo /.undefined -> {{1,2},{3,4}}
This works!
For example, for a built-in function in Mathematica, f, originally f[1] gives {1,2,3}, but I want to let Mathematica gives only {1,3}. A simple method for rewritting f is desired. I don't want to define a new function or totally rewrite f or just dealing with original f's outputs. I want to rewite f.
Thanks. :)
You can use the Villegas-Gayley trick for this.
For the Sin function:
Unprotect[Sin];
Sin[args___]/;!TrueQ[$insideSin]:=
Block[{$insideSin=True,result},
If[OddQ[result=Sin[args]],result]
];
Protect[Sin];
{Sin[Pi],Sin[Pi/2]}
==> {Null,1}
I prefer a method which is functional and reminds me of decorators in Python. http://wiki.python.org/moin/PythonDecorators
First we create the decorator:
OddOnly[x_] := If[OddQ[x], x, Null];
It can then be used as a prefix:
OddOnly#
Sin[Pi]
Null (* Doesn't actually give a result *)
OddOnly#
Sin[Pi/2]
1
A variation of Searke's method that I prefer is:
OddOnly[s_Symbol] :=
Composition[If[OddQ##, #, ##&[]] &, s]
This automatically removes results that are not odd, and it is applied to the function itself, which I find more convenient.
Examples:
OddOnly[Sin] /# {2, Pi, Pi/2}
(* Out[]= {1} *)
Array[OddOnly[Binomial], {5, 5}]
(* Out[]= {{1}, {1}, {3, 3, 1}, {1}, {5, 5, 1}} *)
Could apply a rule of the form
whatever /. _Integer?EvenQ :>Sequence[]
Daniel Lichtblau
Hi I am using Mathematica 5.2. Suppose I have an array list like
In[2]:=lst=Tuples[{0,1},4]
Out[2]={{0,0,0,0},{0,0,0,1},{0,0,1,0},{0,0,1,1},
{0,1,0,0},{0,1,0,1},{0,1,1,0},{0,1,1,1},
{1,0,0,0},{1,0,0,1},{1,0,1,0},{1,0,1,1},
{1,1,0,0},{1,1,0,1},{1,1,1,0},{1,1,1,1}}
Now I want to get 16 arrays from the above array like st1={0,0,0,0}; st2={0,0,0,1}, st3={0,0,1,0}...
How can I get these array lists using a loop. Because if the no. of elements of the above array named lst become larger then it will not be a wise decision to take each of the element of the array lst separately and give their name separately. I tried this like the following way but it is not working...
Do[st[i]=lst[[i]],{i,1,16}]
Plz some body help me in this problem...
It does work, but what you create are the so-called indexed variables. You should access them also using the index, for example:
In[4]:= {st[1], st[2], st[3]}
Out[4]= {{0, 0, 0}, {0, 0, 1}, {0, 1, 0}}
I think what you are trying to do could be done by:
lst = Tuples[{0, 1}, 4];
Table[Evaluate[Symbol["lst" <> ToString[i]]] = lst[[i]], {i, Length#lst}]
So that
lst1 == {0,0,0,0}
But this is not a useful way to manage vars in Mathematica.
Edit
I'll try to show you why having vars lst1,lst2 .. is not useful, and is against the "Mathematica way".
Mathematica works better by applying functions to objects. For example, suppose you want to work with EuclideanDistance. You have a point {1,2,3,4} in R4, and you want to calculate the nearest point from your set to this point.
This is easily done by
eds = EuclideanDistance[{1, 2, 3, 4}, #] & /# Tuples[{0, 1}, 4]
And the nearest point distance is simply:
min = Min[eds]
If you want to know which point/s are the nearest ones, you can do:
Select[lst, EuclideanDistance[{1, 2, 3, 4}, #] == min &]
Now, try to do that same things with your intended lst1,lst2 .. asignments, and you will find it, although not impossible, very,very convoluted.
Edit
BTW, once you have
lst = Tuples[{0, 1}, 4];
You can access each element of the list just by typing
lst[[1]]
etc. In case you need to loop. But again, loops are NOT the Mathematica way. For example, if you want to get another list, with your elements normalized, don't loop and just do:
lstNorm = Norm /# lst
Which is cleaner and quicker than
Do[st[i] = Norm#lst[[i]], {i, 1, 16}]
You will find that defining downvalues (like st[i]) above) is useful when solving equations, but besides that many operations that in other languages are done using arrays, in Mathematica are better carried out by using lists.
Edit
Answering your comment actually I need each element of array lst to find the value of function such as f[x,y,z,k]=x-y+z+k. Such function may be
(#1 - #2 + #3 + #4) & ### lst
or
(#[[1]] - #[[2]] + #[[3]] + #[[4]]) & /# lst
Out:
{0, 1, 1, 2, -1, 0, 0, 1, 1, 2, 2, 3, 0, 1, 1, 2}
HTH!
You can do this:
Table[
Evaluate[
Symbol["st" <> ToString#i]] = lst[[i]],
{i, 1, Length#lst}];
at the end of which try Names["st*"] to see that you now have st1 to st16 defined. You could also do this with MapIndexed, like so:
MapIndexed[(Evaluate#Symbol["sts" <> ToString~Apply~#2] = #1) &, lst]
after which Names["sts*"] shows again that it has worked. Both of these can be done using a loop if this is what you (but I do not see what it buys you).
On the other hand, this way, when you want to access one of them, you need to do something like Symbol["sts" <> ToString[4]]. Using what you have already done or something equivalent, eg,
Table[
Evaluate[stg[i]] = lst[[i]],{i, 1, Length#lst}]
you end up with stg[1], stg[2] etc, and you can access them much more easily by eg Table[stg[i],{i,1,Length#lst}]
You can see what has been defined by ?stg or in more detail by DownValues[stg].
Or is it something else you want?
Leonid linked to a tutorial, which I suggest you read, by the way.
There are N ways of doing this, though like belisarius I have my doubts about your approach. Nonetheless, the easiest way I've found to manage things like this is to use what Mathematica calls "pure functions", like so:
In[1]:= lst = Tuples[{0,1}, 4];
In[2]:= With[{setter = (st[#1] = #2) &},
Do[setter[i, lst[[i]]], {i, Length#lst}]];
Doing it this way, the evaluation rules for special do just what you want. However, I'd approach this without a loop at all, just using a single definition:
In[3]:= ClearAll[st] (* Clearing the existing definitions is important! *)
In[4]:= st[i_Integer] := lst[[i]]
I think if you provide more detail about what you're trying to accomplish, we'll be able to provide more useful advice.
EDIT: Leonid Shifrin comments that if you change the definition of lst after the fact, the change will also affect st. You can avoid this by using With in the way he describes:
With[{rhs = lst},
st[i_Integer] := rhs[[i]]];
I don't know which will be more useful given what you're trying to do, but it's an important point either way.
Maybe something like this?
MapThread[Set, {Array[st, Length#lst], lst}];
For example:
{st[1], st[10], st[16]}
Out[14]= {{0, 0, 0, 0}, {1, 0, 0, 1}, {1, 1, 1, 1}}
Does mathematica have something like "select any" that gets any element of a list that satisfies a criterion?
If you just want to return after the first matching element, use the optional third argument to Select, which is the maximum number of results to return. So you can just do
Any[list_List, crit_, default_:"no match"] :=
With[{maybeMatch = Select[list, crit, 1]},
If[maybeMatch =!= {},
First[maybeMatch],
default]
Mathematica lacks a great way to signal failure to find an answer, since it lacks multiple return values, or the equivalent of Haskell's Maybe type. My solution is to have a user-specifiable default value, so you can make sure you pass in something that's easily distinguishable from a valid answer.
Well, the downside of Eric's answer is that it does execute OddQ on all elements of the list. My call is relatively costly, and it feels wrong to compute it too often. Also, the element of randomness is clearly unneeded, the first one is fine with me.
So, how about
SelectAny[list_List, criterion_] :=
Catch[Scan[ If[criterion[#], Throw[#, "result"]] &, list];
Throw["No such element"], "result"]
And then
SelectAny[{1, 2, 3, 4, 5}, OddQ]
returns 1.
I still wish something were built into Mathematica. Using home-brew functions kind of enlarges your program without bringing much direct benefit.
The Select function provides this built-in, via its third argument which indicates the maximum number of items to select:
In[1]:= Select[{1, 2, 3, 4, 5}, OddQ, 1]
Out[1]= {1}
When none match:
In[2]:= Select[{2, 4}, OddQ, 1]
Out[2]= {}
Edit: Oops, missed that nes1983 already stated this.
You can do it relatively easily with Scan and Return
fstp[p_, l_List] := Scan[ p## && Return## &, l ]
So
In[2]:= OddQ ~fstp~ Range[1,5]
Out[2]= 1
In[3]:= EvenQ ~fstp~ Range[1,5]
Out[3]= 2
I really wish Mathematica could have some options to make expressions evaluated lazily. In a lazy language such as Haskell, you can just define it as normal
fstp p = head . filter p
There's "Select", that gets all the elements that satisfy a condition. So
In[43]:= Select[ {1, 2, 3, 4, 5}, OddQ ]
Out[43]= {1, 3, 5}
Or do you mean that you want to randomly select a single matching element? I don't know of anything built-in, but you can define it pretty quickly:
Any[lst_, q_] :=
Select[ lst, q] // (Part[#, 1 + Random[Integer, Length[#] - 1]]) &
Which you could use the same way::
In[51]:= Any[ {1, 2, 3, 4, 5}, OddQ ]
Out[51]= 3