Получение количества массивов из списка массивов - PullRequest
2 голосов
/ 01 февраля 2011

Привет, я использую Mathematica 5.2. Предположим, у меня есть список массивов вроде

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

Теперь я хочу получить 16 массивов из вышеуказанного массива, например st1 = {0,0,0,0}; st2 = {0,0,0,1}, st3 = {0,0,1,0} ... Как я могу получить эти списки массивов с помощью цикла. Потому что, если нет. элементов вышеупомянутого массива с именем lst становятся больше, тогда не будет мудрым решение взять каждый элемент массива lst отдельно и дать их имя отдельно Я попробовал это следующим образом, но это не работает ...

Do[st[i]=lst[[i]],{i,1,16}]

Пожалуйста, помогите мне решить эту проблему ...

Ответы [ 5 ]

4 голосов
/ 01 февраля 2011

Это работает, но вы создаете так называемые индексированные переменные .Вы должны получить доступ к ним также с помощью индекса, например:

In[4]:= {st[1], st[2], st[3]}

Out[4]= {{0, 0, 0}, {0, 0, 1}, {0, 1, 0}}
3 голосов
/ 01 февраля 2011

Я думаю, что вы пытаетесь сделать:

lst = Tuples[{0, 1}, 4];
Table[Evaluate[Symbol["lst" <> ToString[i]]] = lst[[i]], {i, Length@lst}]  

Так что

lst1 == {0,0,0,0} 

Но это не полезный способ управления переменными в Mathematica.

Редактировать

Я попытаюсь показать вам, почему использование vars lst1,lst2 .. бесполезно, и против - «путь Mathematica».

Mathematica работает лучше, применяя функции к объектам. Например, предположим, что вы хотите работать с EuclideanDistance. У вас есть точка {1,2,3,4} в R 4 , и вы хотите вычислить ближайшую точку от вашего набора до этой точки.

Это легко сделать с помощью

eds = EuclideanDistance[{1, 2, 3, 4}, #] & /@ Tuples[{0, 1}, 4]  

А расстояние до ближайшей точки просто:

min = Min[eds]  

Если вы хотите узнать, какие точки являются ближайшими, вы можете сделать:

Select[lst, EuclideanDistance[{1, 2, 3, 4}, #] == min &]  

Теперь попробуйте сделать то же самое с намеченными lst1,lst2 .. назначениями, и вы найдете это, хотя и не невозможно, очень, очень запутанно.

Редактировать

Кстати, когда у вас есть

lst = Tuples[{0, 1}, 4];  

Вы можете получить доступ к каждому элементу списка, просто набрав

lst[[1]]  

и т.д.. В случае, если вам нужно зациклить. Но опять же, петли НЕ являются способом Mathematica. Например, если вы хотите получить другой список с нормализованными элементами, не зацикливайтесь и просто выполните:

lstNorm = Norm /@ lst   

Что чище и быстрее, чем

Do[st[i] = Norm@lst[[i]], {i, 1, 16}]

Вы обнаружите, что определение понижающих значений (например, st [i]) выше) полезно при решении уравнений, но помимо того, что многие операции, которые в других языках выполняются с использованием массивов, в Mathematica лучше выполнять с использованием списков.

Редактировать

Ответ на ваш комментарий 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. Такая функция может быть

 (#1 - #2 + #3 + #4) & @@@ lst  

или

 (#[[1]] - #[[2]] + #[[3]] + #[[4]]) & /@ lst  

Out:

{0, 1, 1, 2, -1, 0, 0, 1, 1, 2, 2, 3, 0, 1, 1, 2}  

НТН!

2 голосов
/ 01 февраля 2011

Вы можете сделать это:

Table[
    Evaluate[
        Symbol["st" <> ToString@i]] = lst[[i]], 
            {i, 1, Length@lst}];

, в конце которого попробуйте Names["st*"], чтобы увидеть, что у вас теперь определены значения от st1 до st16.Вы также можете сделать это с MapIndexed, например, так:

 MapIndexed[(Evaluate@Symbol["sts" <> ToString~Apply~#2] = #1) &, lst]

, после чего Names["sts*"] снова показывает, что это сработало.И то, и другое можно сделать с помощью цикла, если это то, что вы (но я не вижу, что он вам покупает).

С другой стороны, таким образом, когда вы хотите получить доступ к одному из них, вынужно сделать что-то вроде Symbol["sts" <> ToString[4]].Используя то, что вы уже сделали или что-то эквивалентное, например,

Table[
Evaluate[stg[i]] = lst[[i]],{i, 1, Length@lst}]

, вы получите stg [1], stg [2] и т. Д., И вы можете получить к ним гораздо более легкий доступ, например, Table[stg[i],{i,1,Length@lst}]

Вы можете увидеть, что было определено с помощью ?stg или более подробно с помощью DownValues[stg].

Или это что-то еще, что вы хотите?

Леонид связан с учебникомКстати, я предлагаю вам прочесть.

1 голос
/ 01 февраля 2011

Есть N способов сделать это, хотя, как и belisarius У меня есть сомнения относительно вашего подхода. Тем не менее, я нашел самый простой способ управлять такими вещами, как использовать то, что Mathematica называет «чистыми функциями» , вот так:

In[1]:= lst = Tuples[{0,1}, 4];

In[2]:= With[{setter = (st[#1] = #2) &},
           Do[setter[i, lst[[i]]], {i, Length@lst}]];

Делая это таким образом, правила оценки для специальных делают именно то, что вы хотите. Однако я бы подошел к этому вообще без цикла, просто используя одно определение:

In[3]:= ClearAll[st] (* Clearing the existing definitions is important! *)

In[4]:= st[i_Integer] := lst[[i]]

Я думаю, что если вы предоставите более подробную информацию о том, чего вы пытаетесь достичь, мы сможем дать более полезный совет.

РЕДАКТИРОВАТЬ: Леонид Шифрин комментирует, что если вы измените определение lst после факта, изменение также повлияет на st. Вы можете избежать этого, используя With так, как он описывает:

With[{rhs = lst}, 
  st[i_Integer] := rhs[[i]]];

Я не знаю, что будет более полезным, учитывая то, что вы пытаетесь сделать, но в любом случае это важный момент.

0 голосов
/ 01 февраля 2011

Может быть как то так?

MapThread[Set, {Array[st, Length@lst], lst}];

Например:

{st[1], st[10], st[16]}

Out[14]= {{0, 0, 0, 0}, {1, 0, 0, 1}, {1, 1, 1, 1}}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...