# Patterns with inactive integrals

I am trying to do algebra on unsolved integrals but not getting the pattern-matching right. I want the correlation of f[x] and f[x]+a*d[x], normalized by their self correlations.

crInt[f_, g_, x_] := Inactive[Integrate][Expand[f[x]*g[x]], {x, -Infinity, Infinity}];
defInt[f_, x_] := Inactive[Integrate][f[x], {x, -Infinity, Infinity}];
corr[f_, g_, x_] := crInt[f, g, x] - defInt[f, x]*defInt[g, x];
h1 = corr[f, g, x]/Sqrt[corr[f, f, x]*corr[g, g, x]];
h2 = h1 /. g[x] -> f[x] + a*d[x];
h3 = h2 /. Integrate[q_, {v_, s__}] :> Distribute@Integrate[Expand[q], {v, s}];
h4 = h3 /. Integrate[q1___ r__ q2___, {v_, s__}] /; FreeQ[{r}, v] :> r Integrate[q1 q2, {v, s}]


The Expand/Distribute in the h3 line isn't Expanding the integrand, so the Distribute can't work.

In the h4 line, I'm trying to move any constants outside the integral, but I'm not sure I understand the difference between /. and //.

This Question builds on the discussion from my earlier question: How to do algebra on unevaluated integrals?

• A couple of comments: Distribute won't work, because it has the wrong form (check the documentation). Second: I think to match Integrate, you need to actually put Inactive[Integrate]. Third: It seems like your definitions of the correlation functions and such are creating things like dx^2, which I don't understand. Edit: nope, nevermind, I misinterpreted the ^2 that was attached to the entire integral. Aug 11, 2015 at 21:32

crInt[f_, g_, x_] := Inactive[Integrate][Expand[f[x]*g[x]], {x, -Infinity, Infinity}];
defInt[f_, x_] := Inactive[Integrate][f[x], {x, -Infinity, Infinity}];
corr[f_, g_, x_] := crInt[f, g, x] - defInt[f, x]*defInt[g, x];


Then, define

rule0 = Inactive[Integrate][q_, {v_, s__}] :> Inactive[Integrate][Expand@q, {v, s}];
rule1 = Inactive[Integrate][HoldPattern[Plus[q__]], {v_, s__}] :> (Inactive[Integrate][#, {v, s}] & /@ q);
rule2 = Inactive[Integrate][q1___ r__ q2___, {v_, s__}] /; FreeQ[{r}, v] :> r Inactive[Integrate][q1 q2, {v, s}];


Finally, do

h1 = corr[f, g, x]/Sqrt[corr[f, f, x]*corr[g, g, x]];
h2 = h1 /. g[x] -> f[x] + a*d[x];
h3 = h2 /. rule0;
h4 = h3 /. rule1;
h5 = h4 /. rule2 // Expand;


A couple of things:

• You need to match Inactive[Integrate] rather than Integrate.

• Distribute doesn't work: it would only work if the syntax is Integrate[Plus[a, b, c]] rather than Integrate[Plus[a,b,c], {x, d, e}] (see the documentation). I replaced that with an explicit pattern matching replacement rule, but...

• ...HoldPattern[Plus[q__]] is necessary because, as pointed out by Michael E2 in a comment below, Plus always evaluates, even if the argument is a pattern. So Plus[q__] evaluates to q__ on the left-hand side of the replacement rule, which means the pattern will match any argument, rather than ones that have Plus as a Head.

As for /. vs. //., the best I can say is to experiment; but a couple more notes:

• /. is ReplaceAll. It scans through an expression once, so a + b /. {a -> b, b -> c, c -> d} evaluates to b + c, where a has been replaced by b and b has been replaced by a, but no further replacements occur.

• //. is ReplaceRepeated. It does what /. does, except that it will repeat the procedure over and over again until it can no longer match any of the patterns on the LHS's of the replacement rules. So a + b /. {a -> b, b -> c, c -> d} evaluates to 2 d

(Use Trace to see the process.)

• Re HoldPattern[Plus[q__]] -- you're right on track about Plus evaluating. The LHS of a Rule/RuleDelayed evaluates unless wrapped in HoldPattern. Plus[x], whatever expression x happens to be, evaluates to (the value of) x. So [Plus[q__]] :> replacement is the same as q__ :> replacement. Aug 11, 2015 at 22:27
• @MichaelE2. Thanks for that! It's something that's been bugging me or a long time. Aug 11, 2015 at 23:30
• You're welcome. Aug 11, 2015 at 23:35

You can apply IgnoringInactive to the left hand side of the replacement rule to match without explicitly checking for Inactive.

Lines h3 and h4 would be

h3 = h2 /.
IgnoringInactive@Integrate[q_, {v_, s__}] :>
Distribute@Integrate[Expand[q], {v, s}];
h4 = h3 /.
IgnoringInactive[
Integrate[q1___ r__ q2___, {v_, s__}]] /; FreeQ[{r}, v] :>
r Integrate[q1 q2, {v, s}]


and the distribution would occur.

Hope this helps.