Re: Specifying arguments inside nested functions

• To: mathgroup at smc.vnet.net
• Subject: [mg46130] Re: Specifying arguments inside nested functions
• From: drbob at bigfoot.com (Bobby R. Treat)
• Date: Sat, 7 Feb 2004 04:02:15 -0500 (EST)
• References: <bvvnse\$j7v\$1@smc.vnet.net>
• Sender: owner-wri-mathgroup at wolfram.com

```First a couple of test matrices.

mA = {{a, b, c}, {d, e, f}, {g, h, i}};
mB = {{a, x, y}, {o, e, g}, {q, r, s}};

First solution, not far from what you had in mind:

ClearAll[match, not, matchNone, unmatched]
not = If[#1, False, True, True] &;
match[a_List, b_List] := Or @@ Thread[Equal[a, b]]
matchNone[a_List, b_?MatrixQ] := not[Or @@ (match[a, #] & /@ b)]
unmatched[a_?MatrixQ, b_?MatrixQ] := Select[a, matchNone[#, b] &]
matchNone[#, mB] & /@ mA
unmatched[mA, mB]

Testing:

(matchNone[#1, mB] & ) /@ mA
unmatched[mA, mB]
{False, False, True}
{{g, h, i}}

Here's a second solution, probably more efficient:

ClearAll[matchNone, unmatched]
matchNone[a_List, b_?MatrixQ] := Module[{f},
Nor @@ (Thread[f[Transpose@b, a]] /. f -> MemberQ)
]
unmatched[a_?MatrixQ, b_?MatrixQ] := Select[a, matchNone[#, b] &]

I wonder whether, if mB has a LOT of rows, it would be better to
replace Transpose@b with Union/@Transpose@b or, better yet,
UnsortedUnion (see the Help examples for Union. Also, since Nor will
stop at the first column where there's a match, it's better for large
problems if the columns are in an order that makes that happen early,
most of the time -- if possible. I didn't do any testing like that,
however.

The same test:

(matchNone[#1, mB] & ) /@ mA
unmatched[mA, mB]
{False, False, True}
{{g, h, i}}

Here's the same solution, if you don't have a global called memberQ:

ClearAll[matchNone, unmatched]
matchNone[a_List, b_?MatrixQ] :=
Nor @@ (Thread[memberQ[Transpose@b, a]] /. memberQ -> MemberQ)
unmatched[a_?MatrixQ, b_?MatrixQ] := Select[a, matchNone[#, b] &]

or, even niftier:

ClearAll[matchNone, unmatched]
matchNone[a_List, b_?MatrixQ] := Block[{MemberQ},
unmatched[a_?MatrixQ, b_?MatrixQ] := Select[a, matchNone[#, b] &]

Bobby

koopman at sfu.ca (Ray Koopman) wrote in message news:<bvvnse\$j7v\$1 at smc.vnet.net>...
> I have two matrices, A and B, that have the same number of columns.
> I want to select the rows of A that differ in every position from
> every row of B. So I write
>
>    Select[A, And@@Map[Inner[Unequal,#1,#2,And]&, B]& ]
>
> But that won't work, because I have no way to tell Inner that one of
> its arguments should be the row of A that is being tested by Select,
> and the other argument should be the row of B from Map.
>
> Now, I realize that there are ways around the problem in this
> particular case. For instance, the Select test could be
>
>    And@@Map[FreeQ[Rest[#],First[#]]&, Transpose@Prepend[B,#]]&
>
> which checks B a column at a time and might well be more efficient.
> However, this is not the first time I've run into the problem of
> specifying arguments inside nested functions, and I wonder how other
> people handle it. Is there a general solution, or must I always