Re: confusion about Thread[]
- To: mathgroup at smc.vnet.net
- Subject: [mg56048] Re: [mg56007] confusion about Thread[]
- From: "Wolf, Hartmut" <Hartmut.Wolf at t-systems.com>
- Date: Thu, 14 Apr 2005 08:54:51 -0400 (EDT)
- Sender: owner-wri-mathgroup at wolfram.com
>-----Original Message----- >From: Torsten Coym [mailto:torsten.coym at eas.iis.fraunhofer.de] To: mathgroup at smc.vnet.net >Sent: Wednesday, April 13, 2005 7:11 AM >Subject: [mg56048] [mg56007] confusion about Thread[] > >Hi group, > >given three lists > >wLst = {w1, w2, w3} >zLst = {z1, z2, z3} >cLst = {c1, c2, c3} > >with each element representing a boolean value I want to calculate a >list of the same function applied to the corresponding >elements of wLst, >zLst, cLst respectively. While the expression > > >Thread[Thread[wLst && zLst] || Thread[wLst && cLst] || > Thread[zLst && cLst]] > > >{(w1 && z1) || (w1 && c1) || (z1 && c1), (w2 && z2) || (w2 && c2) || > (z2 && c2), (w3 && z3) || (w3 && c3) || (z3 && c3)} > >does exactly what I want, I wonder why the following approach using a >pure function with three input arguments and a single call of Thread[] >does not give the desired result: > > >Thread[((#1 && #2) || (#1 && #3) || (#2 && #3) & )[wLst, zLst, cLst]] > >({w1, w2, w3} && {z1, z2, z3}) || ({w1, w2, w3} && {c1, c2, c3}) || > ({z1, z2, z3} && {c1, c2, c3}) > >although > >((#1 && #2) || (#1 && #3) || (#2 && #3) & )[w1, z1, c1] > >(w1 && z1) || (w1 && c1) || (z1 && c1) > >implements the desired logical expression and > > >Thread[f[wLst, zLst, cLst]] > >{f[w1, z1, c1], f[w2, z2, c2], f[w3, z3, c3]} > >works the way I expect it. > > >It seems I am a bit disconnected here ... > >Torsten > > Thread evaluates its argument, hence after evaluating... ((#1 && #2) || (#1 && #3) || (#2 && #3) &)[wLst, zLst, cLst] ---> {w1, w2, w3} && {z1, z2, z3} || {w1, w2, w3} && {c1, c2, c3} || {z1, z2, z3} && {c1, c2, c3} ...there is noting left to thread over, and Thread just returns its argument. To reach what you want, you have to suppress the evaluation of the function, but evalute the lists. As... Thread[f[wLst, zLst, cLst]] ---> {f[w1, z1, c1], f[w2, z2, c2], f[w3, z3, c3]} ...we see that substituting for f alone is not enough, we have to apply Or to the resulting list, e.g. Thread[f[wLst, zLst, cLst]] /. f -> (Or @@ ((#1 && #2) || (#1 && #3) || (#2 && #3)) &) Or @@ ReleaseHold[ Thread[Hold[((#1 && #2) || (#1 && #3) || (#2 && #3) &)][wLst, zLst, cLst]]] Or @@ (Thread[Unevaluated[((#1 && #2) || (#1 && #3) || (#2 && #3) &)[##]]] &)[ wLst, zLst, cLst] An alternative way to do it would be: Or @@ (Inner[And, #1, #2, Or] &) @@@ Partition[{wLst, zLst, cLst}, 2, 1, {1, 1}] or Apply[Or, Thread[And[##]] & @@@ Partition[{wLst, zLst, cLst}, 2, 1, {1, 1}], 1] -- Hartmut Wolf