Mathematica не сохраняет переменную - PullRequest
0 голосов
/ 01 июля 2011

Я пытаюсь выполнить этот вложенный цикл, но он не работает.Это не сохранение результата на каждом этапе.Но если я заменю listInitial на Print [], я замечаю, что все изменения сделаны.

Любые предложения ??

For[b = 1, b < 4, b = b + 1,
 For[a = 1, a < 4, a = a + 1,
  For[x = 1, x < 4, x = x + 1,
   For[z = 1, z < 4, z = z + 1, listInitial = 
    If[Random[] > psurvival, 
      ReplacePart[
       InitialMatrix[3, 3, 3, 3], {b, a, x, z} -> 
        InitialMatrix[3, 3, 3, 3][[b]][[a]][[x]][[z]] - 1], 
      InitialMatrix[3, 3, 3, 3], {b, a, x, z} -> 
       InitialMatrix[3, 3, 3, 3][[b]][[a]][[x]][[z]]]]]]]

listInitial // TableForm

Ответы [ 5 ]

3 голосов
/ 01 июля 2011

Я думаю, что ваша проблема в том, что вы ожидаете, что ReplacePart изменится InitialMatrix. Это не. Он изменяет безымянную копию InitialMatrix и возвращает ее как результат, который затем присваивается listInitial. Последний перезаписывается новым значением при каждой итерации цикла, поэтому в конце он содержит только результат замены last . В этот момент все переменные равны 3, последняя замена выглядит следующим образом:

InitialMatrix[3, 3, 3, 3], {3, 3, 3, 3}->InitialMatrix[3, 3, 3, 3][[3]][[3]][[3]][[3]]]

, который фактически ничего не делает. Конечный результат - listInitial, содержащий то, с чего вы начали.

Редактировать
Я только что заметил, что второй аргумент вашего оператора If явно отформатирован для второго экземпляра ReplacePart, который здесь отсутствует,

3 голосов
/ 01 июля 2011

Я спрашиваю, нужен ли вам четырехкратный вложенный цикл For. Если я правильно понимаю ваш код, у вас есть тензор 3 * 3 * 3 * 3, и вы хотите уменьшить начальное значение каждого элемента на 1, если какое-то случайное число превышает некоторый порог. Я предполагаю, что InitialMatrix - это функция, которую вы уже правильно определили, а не какой-то объект.

Конечно, это будет работать:

InitialMatrix[3,3,3,3] + Table[If[RandomReal[]>psurvival,-1,0],{3},{3},{3},{3} ]

В версии 8 вы можете заменить функцию Table на

-RandomVariate[BernoulliDistribution[1-psurvival], {3,3,3,3}]

Если тензор всегда равен n * n * n * n, вы можете написать небольшую функцию:

decrementInitial[n_Integer?Positive,p_?Positive]/; p<=1. :=
InitialMatrix[n,n,n,n] + Table[If[RandomReal[]>p,-1,0],{n},{n},{n},{n} ]

Если вы хотите перезаписать исходную матрицу, потому что вы хотите перебрать функцию выживания за несколько шагов, тогда подойдет что-то подобное с использованием чистой функции (для версии 8).

survivalFn[n_Integer?Positive,p_?Positive,steps_Integer?Positive]/; p<=1. :=
Nest[# + RandomVariate[BernoulliDistribution[1-p], {n,n,n,n}]& , 
InitialMatrix[n,n,n,n], steps]

Или для версий до 8:

survivalFn[n_Integer?Positive,p_?Positive,steps_Integer?Positive]/; p<=1. :=
Nest[# - Table[If[RandomReal[]>p,-1,0],{n},{n},{n},{n} ]& , 
InitialMatrix[n,n,n,n], steps]

Что-то в том, как вы задали вопрос, подсказывало мне, что именно это вы и пытались сделать в конечном итоге.

Дополнительные материалы по запросу от пользователя 825366

Я не уверен, что именно вы хотите знать о функции, но давайте рассмотрим несколько вещей. Сначала функция BernoulliDistribution. документация гласит:

Распределение Бернулли дает значение x = 1 с вероятностью p и x = 0 с вероятностью 1-p.

Вы хотите 0 с вероятностью psurvival и -1 с вероятностью 1-psurvival, так что по сути у вас есть -BernoulliDistribution[1-psurvival].

Далее функция Nest (см. документация ). Это берет некоторую функцию, применяет ее к начальному значению (в данном случае InitialMatrix[3,3,3,3]), затем применяет ее снова к тому, что было результатом этой первой итерации, и повторяет для соответствующего количества шагов.

В определении вложенной функции обычно используется чистых функций . Вы должны прочитать это руководство в документации и это тоже .

Надеюсь, это поможет.

2 голосов
/ 01 июля 2011

Я думаю, вам нужно присвоить результат initialMatrix, чтобы увидеть результат ReplacePart, как в

In[27]:= A={1 ,2 };
A=ReplacePart[A,1->99];
A

Out[29]= {99,2}
0 голосов
/ 02 июля 2011

Я использовал этот метод, чтобы решить это

InitialTable[x_, y_, z_, w_] := 

  MapAt[g, 
   ReplacePart[
    InitialMatrix[x, y, z, w] + 
     ReplacePart[
      Table[If[RandomReal[] > psurvival2, -1, 0], {x}, {y}, {z}, {w}], 
     {{_, _, 1, _} -> 0, {_, _, 2, _} -> 0}],  
   {{_, _, 1, 2} -> 0, {_, _, 1, 3} -> 0}], 
  Flatten[Table[{i, j, k, l}, {i, x}, {j, y}, {k, z}, {l, w}], 3]];

g[x_] := If[x < 0, 0, x];
0 голосов
/ 01 июля 2011

Спасибо, ребята.Я нашел это решение: я думаю, что оно проще и работает.

SetAttributes[myFunction, Listable]
myFunction[x_] := 
 If[Random[] > psurvival, If [x - 1 < 0 , x , x - 1], x]
 myFunction[InitialMatrix[3, 3, 3, 3]] // TableForm
...