Re: Alternative to Table
- To: mathgroup at smc.vnet.net
- Subject: [mg130058] Re: Alternative to Table
- From: daniel.lichtblau0 at gmail.com
- Date: Thu, 7 Mar 2013 04:00:37 -0500 (EST)
- Delivered-to: l-mathgroup@mail-archive0.wolfram.com
- Delivered-to: l-mathgroup@wolfram.com
- Delivered-to: mathgroup-newout@smc.vnet.net
- Delivered-to: mathgroup-newsend@smc.vnet.net
- References: <kh6c7u$b1i$1@smc.vnet.net>
On Tuesday, March 5, 2013 9:13:02 PM UTC-6, Iv=E1n Lazaro wrote: > Dear group: > > I'm trying to build a code that evolves a grid of dimension 2gridDim+1 > over a time timeDim. I managed to build such a code using Table with > only one problem: when the value of timeDim is of thousands, the time > it takes to evaluate is absurd. I tried to find an alternative way to > write this code, using NestList withouth success. NestList is able to > have an interator if I write it like #[[1]]+1, but it doesn't work > when I use it as an element of a list. > > I let here a toy working example. Any input would be most appreciated. > > Iv=E1n. > > > gridDim = 2; timeDim = 3; > list = ConstantArray[0, {2, 2*gridDim + 1, timeDim}]; > > Table[list[[1, i, 1]] = Sin[-(gridDim + 1.) + i], {i, 1, > 2*gridDim + 1}]; > Table[list[[2, i, 1]] = RandomReal[{0, 2*Pi}], {i, 1, 2*gridDim + 1}]; > > > zUpdate[list_, t_] := Module[{lista}, > lista = {}; > lista = list; > Table[If[i + 1 > 2*gridDim + 1, > lista[[1, i, t + 1]] = list[[1, i, t]] (list[[2, 1, t]] - > list[[2, i - 1, t]]), If[ > i - 1 == 0, > lista[[1, i, t + 1]] = list[[1, i, t]] (list[[2, i + 1, t]] - > list[[2, 2*gridDim + 1, t]]), > lista[[1, i, t + 1]] = list[[1, i, t]] (list[[2, i + 1, t]] - > list[[2, i - 1, t]])]], > {i, 1, 2*gridDim + 1}]; > lista > ]; > > > pUpdate[list_, t_] := Module[{lista}, > lista = {}; > lista = list; > Table[If[i + 1 > 2*gridDim + 1, > lista[[2, i, t + 1]] = Mod[list[[1, i, t + 1]] (list[[2, 1, t]] - > list[[2, i - 1, t]]), 2*Pi], > If[i - 1 == 0, > lista[[2, i, t + 1]] = Mod[list[[1, i, t + 1]] (list[[2, i + 1, > t]] - list[[2, 2*gridDim + 1, t]]), 2*Pi], > lista[[2, i, t + 1]] = Mod[ list[[1, i, t + 1]] (list[[2, i + 1, > t]] - list[[2, i - 1, t]]), 2*Pi]]], {i, 1, 2*gridDim + 1}]; > lista > ]; > > > Do[ > list = zUpdate[list, i]; > list = pUpdate[list, i];, {i, 1, timeDim - 1}]; > list Your update functions are doing approximately infinitely many array copies. Instead you could alter the thing in place by using HoldFirst attributes for those functions. Below is pedestrian Do-loop code for this. I also simplified the updates by making use of Mod to handle the iterator edge value cases. I will illustrate on an example where the relevant dimensions are 200 and 3000 respectively. gridDim = 200; timeDim = 3000; list = ConstantArray[0, {2, 2*gridDim + 1, timeDim}]; AbsoluteTiming[ Do[list[[1, i, 1]] = Sin[-(gridDim + 1.) + i], {i, 1, 2*gridDim + 1}]; Do[list[[2, i, 1]] = RandomReal[{0, 2*Pi}], {i, 1, 2*gridDim + 1}];] Out[3]= {0.035499, Null} SetAttributes[zUpdate, HoldFirst] zUpdate[list_, t_] := Do[list[[1, i, t + 1]] = list[[1, i, t]] *(list[[2, Mod[i + 1, 2*gridDim + 1, 1], t]] - list[[2, Mod[i - 1, 2*gridDim + 1, 1], t]]), {i, 1, 2*gridDim + 1}] SetAttributes[pUpdate, HoldFirst] pUpdate[list_, t_] := Do[list[[2, i, t + 1]] = Mod[list[[1, i, t + 1]] (list[[2, Mod[i + 1, 2*gridDim + 1, 1], t]] - list[[2, Mod[i - 1, 2*gridDim + 1, 1], t]]), 2*Pi], {i, 1, 2*gridDim + 1}] Now run the thing. AbsoluteTiming[Do[zUpdate[list, i]; pUpdate[list, i];, {i, 1, timeDim - 1}];] Out[8]= {18.619950, Null} Daniel Lichtblau Wolfram Research