Services & Resources / Wolfram Forums / MathGroup Archive
-----

MathGroup Archive 2013

[Date Index] [Thread Index] [Author Index]

Search the Archive

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



  • Prev by Date: Re: Mathematica and Lisp
  • Next by Date: Re: Strange behavior of System Modeler
  • Previous by thread: Alternative to Table
  • Next by thread: Re: Alternative to Table