3
$\begingroup$

I want to divide a product into two pieces, one is the terms of form f[x, _], the other is the leftover factors free of x:

rule = Times[fac_., (fxs : Repeated[f[x, _]])] /; FreeQ[Times[fac], x] :> FAC[Times[fac]]*FX[Times[fxs]] 

For example:

Replace[f[y, 1]*f[x, 1]*f[x, 2], rule] (* FAC[f[y, 1]] FX[f[x, 1] f[x, 2]] *) 

I use fac_. in rule because there may be no other coefficients present. For example, I hope

Replace[f[x, 1]*f[x, 2], rule] 

returns

FX[f[x, 1] f[x, 2]] 

but the actual output is

(* f[x, 1] f[x, 2] *) 

In fact, the following returns False:

MatchQ[f[x, 1]*f[x, 2], Times[fac_., (fxs : Repeated[f[x, _]])] /; FreeQ[Times[fac], x]] 

It seems that _. does not work. Why?

$\endgroup$
8
  • $\begingroup$ Can you give an example that contains both factors with x and ones without x, together with your expected output? $\endgroup$ Commented Oct 2, 2024 at 13:57
  • $\begingroup$ @MarcoB Actually OP has provided both. I've modified the typesetting a little to make it more obvious. $\endgroup$ Commented Oct 2, 2024 at 14:30
  • 1
    $\begingroup$ Condition seems part of the problem. Try it with Optional[fac_?(FreeQ[#1, x] &)] instead of fac_. ... /; ... $\endgroup$ Commented Oct 2, 2024 at 19:36
  • $\begingroup$ @Michael E2, you are right. I add Condition for Optional in a wrong form. But unluckly, your suggestion does not work either. Now I use a a rule list for my exception {HoldPattern@Times[fxs : Repeated[f[x, _]]] :> FX[Times[fxs]], Times[fac_ /; FreeQ[x][fac], (fxs : Repeated[f[x, _]])] :> FAC[Times[fac]]*FX[Times[fxs]] }. But I still want to know how to use Optional with Condition in this example. $\endgroup$ Commented Oct 3, 2024 at 6:06
  • 1
    $\begingroup$ My understanding is, the "apply to" in document actually means "directly apply to". We can see the example is x_ : 1 /; OddQ[x] (Condition and Optional are next to each other), and this results in a warning. It's not your case, I think. $\endgroup$ Commented Oct 5, 2024 at 14:24

2 Answers 2

2
$\begingroup$

The OP requires Condition, and probably they require Optional, too. If not, then this:

Since Times[] is 1:

rule = Times[fac___, (fxs : f[x, _] ..)] /; FreeQ[Times[fac], x] :> FAC[Times[fac]]*FX[Times[fxs]]; Replace[f[y, 1]*f[y, 3]*f[x, 1]*f[x, 2], rule] (* FAC[f[y, 1] f[y, 3]] FX[f[x, 1] f[x, 2]] *) Replace[f[x, 1]*f[x, 2], rule] (* FAC[1] FX[f[x, 1] f[x, 2]] *) 

This technically meets the requirements of Condition and Optional, but in light of the foregoing, it feels a cheat:

rule = Times[Optional[fac___, 1], (fxs : f[x, _] ..)] /; FreeQ[Times[{fac}], x] :> FAC[Times[fac]]*FX[Times[fxs]] 
$\endgroup$
2
  • $\begingroup$ Yeah, You are right, good solution for my purpose, I should have thought of that earlier. Thank you so much $\endgroup$ Commented Oct 5, 2024 at 11:32
  • $\begingroup$ But, to go further, how to make Replace[f[x, 1], rule] return FAC[1]*FX[f[x, 1]]? $\endgroup$ Commented Oct 5, 2024 at 11:48
2
$\begingroup$

Maybe like this (post-process to taste)?

isolateXterms[expr_] := Module[{vars = Variables[expr]}, vars = Complement[vars, Select[vars, ! FreeQ[#, x] &]]; FactorTermsList[expr, vars] ] isolateXterms[f[y, 1]*f[x, 1]*f[x, 2]] (* Out[421]= {1, f[x, 1] f[x, 2], f[y, 1]} *) 
$\endgroup$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.