Re: large lists with variable and if condition (vrs. 8.0.4)
- To: mathgroup at smc.vnet.net
- Subject: [mg124702] Re: large lists with variable and if condition (vrs. 8.0.4)
- From: Bill Rowe <readnews at sbcglobal.net>
- Date: Wed, 1 Feb 2012 03:50:09 -0500 (EST)
- Delivered-to: l-mathgroup@mail-archive0.wolfram.com
On 1/31/12 at 5:39 AM, kristophs.post at web.de (Chris) wrote: >I would like to construct a large list or large table with some data >and one unknown variable which I need for optimization purposes in >say a for loop. Constructing the whole list at each iteration is >time consuming and slows the optimization down. >First, I present some code that works just fine in order to get the >idea: >(*inputs) leg = 100; data = RandomReal[{}, leg]; >(*constructing the list with the data in which g is a non-specfied >variable*) Clear[list, list2, tab]; list = Table[(data[[i]] - >data[[leg - i + 1]])/g, {i, 1, leg}]; a faster way to construct this table would be list = (data - Reverse[data])/g; This avoids using Part which can slow things down. >(*specifying the function and the result*) tab[k_] := list /. g >->k; tab[1] >Now the following code does not work and I don't know why. >list2= Table[If[Abs[(data[[j]]-data[[i]])/x]<1.,.75 (1.-((data[[j]]- >data[[i]])/x)^2),0.],{i,1,leg},{j,1,leg}]; mat[bw_Real]:=list/.x->bw >It seems to me, when looking at list2, that Mathematica is not >evaluating the when-part of the if-function when the if-part depends >on the unknown variable. Mathematica is not evaluating this because it cannot. It is impossible to determine whether Abs[(data[[j]]-data[[i]])/x] is less than one if x is not defined. >Constructing the list as: >mat[bw_Real]:=Table[If[Abs[(data[[j]]-data[[i]])/bw]<1.,.75 (1.- >((data[[j]]-data[[i]])/bw)^2),0.],{i,1,leg},{j,1,leg}]; is not an >option because it slows things down. Here too, the use of Part can be avoided. Using your code I get with x = .5: In[34]:= Timing[ list2 = Table[ If[Abs[(data[[j]] - data[[i]])/x] < 1., .75 (1. - ((data[[j]] - data[[i]])/x)^2), 0.], {i, 1, leg}, {j, 1, leg}];] Out[34]= {0.053099,Null} Using functional constructs I get: In[35]:= Timing[ b = Map[If[# != 0, .75 (1 - #^2), 0] &, Clip[Outer[Subtract, data, data]/x, {-1, 1}, {0, 0}], {2}] + SparseArray[{Band[{1, 1}] -> .75}, {leg, leg}];] Out[35]= {0.027723,Null} and In[36]:= list2 == b Out[36]= True Note, things will be slower if you defer assigning a value to x then later assign a value using a replacement rule. Pattern matching definitely tends to slow things down. Faster would be to use Block to temporarily assign a value to x. That is: In[37]:= d = list2/g; In[38]:= Timing[c = d /. g -> 1;] Out[38]= {0.015705,Null} In[39]:= Timing[y = Block[{g = 1}, d];] Out[39]= {0.004637,Null} In[40]:= c == y Out[40]= True