Mathematica不保存变量

时间:2011-06-30 23:02:26

标签: wolfram-mathematica mathematical-optimization

我尝试执行此嵌套循环,但它无法正常工作。它并没有在每个阶段保存结果。但如果我用Print []替换listInitial,我会观察到所有的更改都已完成。

有什么建议吗?

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 个答案:

答案 0 :(得分:3)

我认为您的问题是,您希望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的第二个实例,这里没有,

答案 1 :(得分:3)

我怀疑你是否需要一个四重嵌套的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]

关于你问这个问题的方式向我提出这是你最终想要做的事情。

来自user825366的其他材料

我不确定你想知道关于这个功能的确切内容,但让我们来看看。首先是BernoulliDistribution函数。 documentation说:

  

伯努利分布给出值x = 1,概率为p,x = 0,概率为1-p。

你希望0概率psurvival和-1概率1-psurvival,所以基本上你有-BernoulliDistribution[1-psurvival]

接下来是Nest函数(请参阅documentation)。这需要一些函数,将它应用于起始值(在本例中为InitialMatrix[3,3,3,3]),然后将其再次应用于第一次迭代的结果,并迭代适当的步数。

在要嵌套的函数的定义中,通常使用纯函数。您应该阅读文档中的this guidethis one too

我希望有所帮助。

答案 2 :(得分:2)

我认为您需要将结果分配给initialMatrix以查看ReplacePart的结果,如

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

Out[29]= {99,2}

答案 3 :(得分:0)

谢谢你们。我发现这个解决方案: 我认为这是更容易的,它正在发挥作用。

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

答案 4 :(得分:0)

我用这种方法来解决这个问题

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];