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