rajib arefin
rajib arefin

Reputation: 35

Getting a number of arrays from an array list

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...

Upvotes: 2

Views: 549

Answers (5)

Dr. belisarius
Dr. belisarius

Reputation: 61046

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!

Upvotes: 3

Pillsy
Pillsy

Reputation: 9901

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.

Upvotes: 1

acl
acl

Reputation: 6520

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.

Upvotes: 2

681234
681234

Reputation: 4284

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}}

Upvotes: 0

Leonid Shifrin
Leonid Shifrin

Reputation: 22579

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}}

Upvotes: 4

Related Questions