MathGroup Archive 1999

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

Search the Archive

Re: the simplest way?

  • To: mathgroup at smc.vnet.net
  • Subject: [mg16462] Re: [mg16350] the simplest way?
  • From: "Wolf, Hartmut" <hwolf at debis.com>
  • Date: Sat, 13 Mar 1999 02:22:00 -0500
  • Organization: debis Systemhaus
  • References: <199903110716.CAA12191@smc.vnet.net.>
  • Sender: owner-wri-mathgroup at wolfram.com

Dear Antoine;

Antoine Zahnd schrieb:
> 
> I have two questions with lists, each time to avoid the Length function.
> 
> 1) For example, how to write a function that will go thru the elements of a
> list of
> integers, and will return False as soon as an odd number is found, without
> using
> Length?
> 
> With Length it is easy, but not so clean ...
> f[l_]:= Block[{k},For[k=1,k<=Length[l],k++,If[OddQ[l[[k]]],Return[True]]];
> False];
> 
> 2) Is it possible to write the following function without Length?
> 
> l={1,2,3};
> Table[ReplacePart[l,l[[i]]-1,i],{i,1,Length[l]}]
> {{0,2,3},{1,1,3},{1,2,2}}
> 
> More generally, is there a way to write something like:
> (for x in l ... collect (f x) ) , and the collection of the (f x) are
> returned
> in a list?
> 
> I don't see how to write a Lisp style dolist function in Mathematica
> without the Length!
> 
Antoine, I would like to add something to my mail from yesterday. I
proposed:

In[1]:=l=2*Range[100000];//Timing
Out[1]={1.652 Second,Null}

In[2]:=l1=Append[l, 1];//Timing
Out[2]={0.101 Second,Null}

In[3]:=l2=Prepend[l, 1];//Timing
Out[3]={0.1 Second,Null}

In[4]:=Or @@ OddQ /@ l1 //Timing
Out[4]={1.342 Second,True}

In[5]:=Or @@ OddQ /@ l2 //Timing
Out[5]={1.302 Second,True}

OddQ is mapped over the lists which is fast, then Or applied evaluates
it arguments, quitting when it can decide, i.e. as soon as it finds
False.

Now you can use this property for a performance boost, when evaluating
the mapped function delayed, that means only when OddQ wants its result:

In[13]:=Or @@ OddQ /@ Hold @@ l1 //Timing
Out[13]={1.843 Second,True}

In[14]:=Or @@ OddQ /@ Hold @@ l2 //Timing
Out[14]={0.871 Second,True}

So things seem to be made a litte worse for l1 (with an  Odd number at
the end) but this is only apparent because OddQ is such a simple
function that takes nearly no time to execute; for l2 (with the Odd
number at the beginning we get a clear advantage.

This can be made more evident by defining a "slow OddQ"

In[47]:=slowOddQ[n_] := (For[c=0, ++c<10000, Null];OddQ[n])

In[48]:=slowOddQ[5]//Timing
Out[48]={0.831 Second,True}

We have to test more modestly:

In[12]:=sl=2*Range[5]
Out[12]={2,4,6,8,10}

In[15]:=sl1 = Append[sl,1]
Out[15]={2,4,6,8,10,1}

In[16]:=sl2=Prepend[sl,1]
Out[16]={1,2,4,6,8,10}


In[49]:=Or @@ slowOddQ /@ Hold @@ sl1 //Timing
Out[49]={4.967 Second,True}

In[50]:=Or @@ slowOddQ /@ Hold @@ sl2 //Timing
Out[50]={0.831 Second,True}

Which now makes a significant difference!

Trying that on or prior list wth 100000 Elements would still take
something around one second for l2 but about 80000 seconds for l1 (which
is more than a day and a night).


>3) I'm not quite shure about what you want, isn't it just?
>
>    f /@ Select[l, predicate]
>
Perhaps it's

     Scan[f, Select[l, predicate]]

what you are looking for; this when the functional values of f are not
needed, but only its procedural effects (side effects).

---Hartmut
__________________________________________________
Hartmut Wolf, debis Systemhaus, Darmstadt, Germany



  • Prev by Date: Re: Position of element in a list
  • Next by Date: Re: Subscripted Variables
  • Previous by thread: the simplest way?
  • Next by thread: Re: the simplest way?