Also, generally built-in functions do not know about problem symmetries and properties.
Some times it is beneficial to create simplified versions of such functions, but with correct symmetries in mind.
As an example of such approach, once I had a problem to determine Fourier Coefficient of a function composed of different trigonometric functions.
The build-in
FourierCoefficient[] will take forever in this case and it can't parallelized. Example:
(* My FourierCoefficient for *)
(* 2-Harmonic function coeffs. *)
Expansion2D2F[function_, args_List] := Module[
{FUNCTION, ARGS, OUTPUT = {__, __}, a, b, ZERO},
{
Parallelize[
ARGS = args;
ZERO = Coefficient[Expand[TrigToExp[function]] /. E^a_ -> b, b, 0];
FUNCTION = List @@ Expand[Expand[TrigToExp[function]] - ZERO]
/. a_ E^b_ -> {a, b}
/. {a_ ARGS[[1]] + b_ ARGS[[2]] -> {a, b}}
/. {a_ ARGS[[1]] -> {a, 0}}
/. {a_ ARGS[[2]] -> {0, a}} ;
OUTPUT[[1]] =
Join[Take[
Flatten[FUNCTION, 1], {1, Length[Flatten[FUNCTION, 1]], 2}]];
OUTPUT[[2]] =
Join[Im[Take[
Flatten[FUNCTION, 1], {2, Length[Flatten[FUNCTION, 1]], 2}]]];
OUTPUT
, Method -> "FinestGrained"]
}];
In[3]:= f = A Cos[f1] Sin[2 f2] + B Sin[4 f1] Cos[3 f2] ;
In[4]:= (* EXAMPLE *)
Expansion2D2F[f, {f1, f2}][[1]] // AbsoluteTiming
Out[4]= {0.0170010, ...}
In[5]:= AbsoluteTiming[{FourierCoefficient[f, f1, n],FourierCoefficient[f, f2, m]}]
Out[5]= {0.2440139, ... }
I.M.