For example
{a + b} == {c + d} // Thread
(*{a + b == c + d}*)
how to get {a + b} == {c + d}
from {a + b == c + d}
?
This is my try
Equal @@ List /@ Join @@ {a + b == c + d}
Are there other ways to do this?
For example
{a + b} == {c + d} // Thread
(*{a + b == c + d}*)
how to get {a + b} == {c + d}
from {a + b == c + d}
?
This is my try
Equal @@ List /@ Join @@ {a + b == c + d}
Are there other ways to do this?
One way would be
Distribute[{a + b == c + d}, Equal]
Same as
Thread[{a + b == c + d}, Equal]
More universal
{a + b == c + d}/. f_[g_[x_, y_]] -> g[f[x], f[y]]
{Thread[Total@{a == b, c == d}, Equal]}
, another way would be: Inner[Plus, Sequence @@ {a == b, c == d}, Equal]
$\endgroup$
– panda-34
Jul 12 '13 at 20:48
Thread
way. It seems more natural in this case, where threading is basically transposition with different heads. In fact, it seems more universal than the replacement rule, certainly with respect to number of arguments, but also considering that one specifies the head for Thread
in the first place, either List
by default or explicitly by it optional second argument.
$\endgroup$
– Michael E2
Jul 12 '13 at 21:17
The Thread
operation is not completely invertible in all cases, but if we assume that
Thread
, all arguments had the same head and length,then the expression can be unthreaded. Perhaps others can extend this.
Here, in unthread[expr, h]
, if expr
is of the form
f[h[a1, a2,...], h[b1, b2,...],...]
the the result will be
h[f[a1, b1,...], f[a1, b2,...],...]
The default for h
is List
. Thus unthread[f[h[a1, a2,...],..., h]
undoes Thread[h[f[a1, b1,...],...], f]
.
Clear[unthread];
unthread::usage = "unthread[f[args], h] \"unthreads\" f over args each with head h";
unthread::tdlen = "Objects of unequal length in `` cannot be uncombined. :)";
unthread::head = "Objects in `` not all of type ``.";
unthread[expr_, h_: List] /;
(Length@DeleteDuplicates[Length /@ expr] == 1 ||
(Message[unthread::tdlen, expr]; False)) &&
(DeleteDuplicates[Head /@ List @@ expr] == {h} ||
(Message[unthread::head, expr, h]; False)) :=
With[{h2 = Head[expr]}, h @@ h2 @@@ Transpose[List @@ List @@@ expr]];
unthread[expr_, h_] := expr; (* return expressions that do not satisfy criteria *)
Examples
unthread[{a + b == c + d}, Equal]
(* {a + b} == {c + d} *)
unthread[g[f[a, aa], f[b, bb], f[c, cc]], f]
(* f[g[a, b, c], g[aa, bb, cc]] *)
unthread[g[f[a, aa], f[b, bb], f[c, cc, ccc]], f]
(* unthread::tdlen: Objects of unequal length in g[f[a,aa], f[b,bb], f[c,cc,ccc]]
cannot be uncombined. :) *)
(* g[f[a, aa], f[b, bb], f[c, cc, ccc]] *)
unthread[g[f[a, aa], f[b, bb], h[c, cc]], f]
(* unthread::head: Objects in g[f[a,aa], f[b,bb], h[c,cc]] not all of type f. *)
(* g[f[a, aa], f[b, bb], h[c, cc]] *)
An example in which two different Thread
operations yield the same output, which shows Thread
is not completely reversible.
Thread[f[g[a, b, c], g[aa, bb, cc], d], g]
(* g[f[a, aa, d], f[b, bb, d], f[c, cc, d]] *)
Thread[f[g[a, b, c], g[aa, bb, cc], g[d, d, d]], g]
(* g[f[a, aa, d], f[b, bb, d], f[c, cc, d]] *)
Map[List, {a + b == c + d}, {2}]
$\endgroup$ – Dr. belisarius Jul 12 '13 at 17:15{a + b == c + d} /. f_[x_, y_] :> f[{x}, {y}]
(only in special cases) $\endgroup$ – Kuba♦ Jul 12 '13 at 17:16Equal @@ Tuples@{a + b == c + d}
=> {a + b} == {c + d} $\endgroup$ – user1066 Jul 12 '13 at 23:47