Thread


First an example of Thread is given in it's simplest form.  When used in this
simple form Thread takes an expression with arguments that are all lists of
equal length.

ClearAll["Global`*"] ;  Thread[f[{x1, y1}, {x2, y2}, {x3, y3}]]

{f[x1, x2, x3], f[y1, y2, y3]}


In the next cell we see Thread automatically adapts if one or more elements
aren't lists.

Thread[f[a, {y1, y2, y3}, {z1, z2, z3}, d]]

{f[a, y1, z1, d], f[a, y2, z2, d], f[a, y3, z3, d]}


The next three examples have frequent applications.  They have the same form
an example above but it may not look that way because infix operators
(→, ==) are used.

Thread[{opt1, opt2, opt3, opt4} False]

{opt1False, opt2False, opt3False, opt4False}

Thread[{w, x, y, z}  {1.2, 3.2, 4.2, 5.2}]

{w1.2, x3.2, y4.2, z5.2}

Thread[{w, x, y, z}  {1.2, 3.2, 4.2, 5.2}]

{w == 1.2, x == 3.2, y == 4.2, z == 5.2}


As indicated above Thread works over lists by default.  In the next example
some of the expressions at level 1 of (lst1) aren't lists.  In a case such as
this the expressions that aren't lists are copied.

lst1 = f[{x1, y1}, {x2, y2}, {x3, y3},           g[x4, y4], g[x5, y5], g[x6, y6]] ;    Thread[lst1]

{f[x1, x2, x3, g[x4, y4], g[x5, y5], g[x6, y6]], f[y1, y2, y3, g[x4, y4], g[x5, y5], g[x6, y6]]}


Thread will work over a different head if one is provided as a second
argument.  The next line threads the same expression as the last one, but
this time it threads over (g) instead of threading over list.  Similar to the
last example expressions that didn't have the head (g) were copied.

Thread[lst1, g]

g[f[{x1, y1}, {x2, y2}, {x3, y3}, x4, x5, x6], f[{x1, y1}, {x2, y2}, {x3, y3}, y4, y5, y6]]


In the next line Thread is provided a second and third argument.  The third
argument tells Thread to only thread across the first three arguments.

lst2 = f[g[x1, y1], g[x2, y2],           g[x3, y3], g[x4, y4], g[x5, y5]] ;    Thread[lst2, g, 3]

g[f[x1, x2, x3, g[x4, y4], g[x5, y5]], f[y1, y2, y3, g[x4, y4], g[x5, y5]]]


In the next line Thread is given a third argument which says to only thread
over arguments 2 through 4.

Thread[lst2, g, {2, 4}]

g[f[g[x1, y1], x2, x3, x4, g[x5, y5]], f[g[x1, y1], y2, y3, y4, g[x5, y5]]]


Finally Thread is given (-3) as a third argument.  This means to only thread
over the last three arguments.

Thread[lst2, g, -3]

g[f[g[x1, y1], g[x2, y2], x3, x4, x5], f[g[x1, y1], g[x2, y2], y3, y4, y5]]


Roman Meader give the elegant program below which automatically threads
listable functions across the head Equal.  The program is posted in
MathSource under Enhancements, Algebraic, 0202-204.  The code for this
enhancement is shown in the next cell.

Unprotect[Equal] ;     listableQ[f_] := MemberQ[Attributes[f], Listable] ;    Equal/:  ... listableQ[___, _Equal, ___] :=      Thread[Unevaluated[lhs], Equal] ;    Protect[Equal] ;


The program above allows one to 'add' two equations in the next cell.

Clear[x] ;    eqn1 = (4 - 2x + x^2 == 0) ; <br /> eqn2 = (5 + 6x == 0) ; <br /> eqn1 + eqn2

9 + 4 x + x^2 == 0


Created by Mathematica  (May 16, 2004)

Back to Ted’s Tricks index page