sjdh
sjdh

Reputation: 4006

Combining patterns to collect terms

I have a Mathematica expressions (called expr), which is a sum of many terms. Also I have a list (called var) with some of the variables and functions that may appear in some of these terms.

The first thing I would like to do is to extract terms that contain a number of variables and functions a certain number of times. For example if the var = {a, f[_]}, then I may want to extract all terms that contain the variable a one time and the function f 2 times. f[f[a + b]] is an example of a term that satisfies these criteria.

The second thing I would like to do, is to create a list (called output) that contains all terms of the original expression one time. The list should be such that it groups terms according to the number of times they contain the variables and functions specified in var. For var = {a, f[_]} the output would be output = {{sum of those terms containing 0 * a and 0 * f[_], "sum of..." 1 * a and 0 f, "sum of..." 2a 0f, ... }, {"sum of..." 0a 1f, "sum of..." 1a, 1f, ... }}

Given a solution to problem 2, it is easy to solve problem 1: To extract a certain term of the expression, you just have to pick the right element from the list output. For that reason I tried to solve problem 2. To keep things clear I started with a simple expression, containing just one term. First I generate a list of patterns

expr = f[a + f[y]]
var = {{a, 1}, {f[_], 3}}
basicpattern[symbol_, n_, term_] = 
Hold[Table[Count[{term}, symbol, 10] == i, {i, 0, n}]]
basicpattern[#1, #2, expr] & @@@ var // ReleaseHold

The output is

{{False, True}, {False, False, True, False}}

The interpretation is that: variable a occurs one time, function f appears 2 times. Now I would like to take the outer product of the lists inside basicpattern to make combinations of patterns. Then the new list of patterns can be used together with Cases to select terms from expr and put them in a list.

Here I am stuck: How to take the outer product of the lists inside a list? I guessed

Outer[And, {{True, False}, {True, False, False, False}}, 1]

But this does not give the eight terms.

Update

With Sjoerd's help I came a bit further.

expr = f[a + f[y]];
var = {{a, 1}, {f[_], 3}};
basicpattern[symbol_, n_, term_] := 
Table[Hold[Count[{term}, symbol, 10]] == i, {i, 0, n}];
basicpattern[#1, #2, expr] & @@@ var;
Outer[And, ##] & @@ %;
test = %[[2, 3]]
%// ReleaseHold

Gives as output

Hold[Count[{f[a + f[y]]}, a, 10]] == 1 &&
Hold[Count[{f[a + f[y]]}, f[_], 10]] == 2
True

The interpretation is that f[a + f[y]] contains one time a and two times f[_]. The outer product is a list of tests like these.

Suppose I change expr to

expr = f[a + f[y]] + g[z] + y^2 - 13 x + 12a + a f[x]

How can I use the content of test to collect all terms containing one a and two times f[_]?

Upvotes: 1

Views: 798

Answers (1)

Sjoerd C. de Vries
Sjoerd C. de Vries

Reputation: 16232

Yours is a long story, but I guess your question boils down to:

How to take the outer product of the lists inside a list?

If this is the only thing you wanted to know you were close. It can be done simply like this:

booleanLists = {{True, False}, {True, False, False, False}};

Outer[And, ##] & @@ booleanLists

(* ==>  {{True, False, False, False}, {False, False, False, False}} *)

Upvotes: 1

Related Questions