# How to integrate assuming some integrals are named constants?

Imagine having some undefined functions $X(x),\ Y(x), \dots$, and all we know about them is that they integrate to specific constants, i.e. $$\bar X := \int_{-\infty}^\infty \text d x \ |X(x)|^2, \quad \bar Y := \int_{-\infty}^\infty \text d x \ |Y(x)|^2, \quad \dots$$

What I want Mathematica to do is calculating the integral $\int_{-\infty}^\infty \text d x \ f(x)$ of a function that looks approximately like $$f(x) = a X(x)X(x)^* + bY(x)Y(x)^* + \dots$$ and then return something like $$a \bar X + b \bar Y + \dots\ .$$ Do you have any idea, how i can do this in Mathematica? In fact my $f(x)$ is a bit more complicated, but this example should illustrate my problem.

You could distribute your integral over sum, pull constants out of integral, and replace known integrals, that are left, with your constants.

Linearity of integral can be exploited with following function:

integrateDistribute = # /.
(integ : Integrate | Inactive@Integrate)[f_, vars__] :>
Module[{h, constQ, factRule, distRule},
constQ = FreeQ@Flatten@Replace[Alternatives@vars, {
{x_Symbol, ___} :> x,
{xs__Symbol} \[Element] _ :> Alternatives@xs,
Except@_Symbol -> Alternatives[]
}, {1}];
factRule = h[c_?constQ x_.] :> c Replace[h@x, distRule];
distRule = h@sum_Plus :> (Replace[h@#, factRule]& /@ sum);
h@f /. {factRule, distRule} /. h[a_] :> integ[a, vars]
]&;


Using it you can do:

Integrate[f[x], {x, -∞, ∞}]
% /. f[x] -> a X[x] X[x]\[Conjugate] + b Y[x] Y[x]\[Conjugate] + g[x]
% // integrateDistribute
% /. (Integrate[#[x] #[x]\[Conjugate] , {x, -∞, ∞}] -> OverBar@# & /@ {X, Y})


$\int_{-\infty }^{\infty } f(x) \, dx$

$\int_{-\infty }^{\infty } \left(a\,X(x)X(x)^*+b\,Y(x)Y(x)^*+g(x)\right) \, dx$

$a \int_{-\infty }^{\infty } X(x) X(x)^* \, dx+b \int_{-\infty }^{\infty } Y(x) Y(x)^* \, dx+\int_{-\infty }^{\infty } g(x) \, dx$

$a\,\bar{X}+b\,\bar{Y}+\int_{-\infty }^{\infty } g(x) \, dx$

Here's an unorthodox approach. Since $\int_{-\infty }^{\infty } f(x) \, dx$ is just FourierTransform[f[x], x, 0] (up to suitable FourierParameters), you could use UpValues to teach Mathematica about FourierTransform linearity. For example:

SetOptions[FourierTransform, FourierParameters->{0, 2Pi}];

(* distribution *)
x /: FourierTransform[a_Plus, x, 0] := Distribute[
Unevaluated @ FourierTransform[a, x, 0]
]

(* scalar extraction *)
x /: FourierTransform[HoldPattern[Times[a__]],x,0] := Module[
{depends=InternalDependsOnQ[#,x]& /@ {a}, i, d},

i = Pick[{a}, depends, False];
(
d=Pick[{a}, depends, True];
Times@@i FourierTransform[Times@@d, x, 0]
) /; Length[i]>0
]

(* known integrals *)
x /: FourierTransform[X[x] Conjugate[X[x]], x, 0] := OverBar[X]
x /: FourierTransform[Y[x] Conjugate[Y[x]], x, 0] := OverBar[Y]


Then, we have

FourierTransform[a X[x] Conjugate[X[x]] + b Y[x] Conjugate[Y[x]] + Exp[-x^2], x, 0] //TeXForm


$a \bar{X}+b \bar{Y}+\sqrt{\pi }$

However, if you want to use this kind of approach, it is probably better to just use DownValues on a different head, e.g.:

transform[a_Plus, x] := Distribute @ Unevaluated @ transform[a,x]
`

etc.