2
$\begingroup$

I have an expression of the form

C1 Exp[a1+b1 x] + C2 Exp[a2+b2 x] + C3 Exp[a3+b3 x] + ...

Where variables C, a, b are all expressions (some simpler than others) that do not depend on x. I don't know beforehand what all of these expressions look like.

I would like to first manipulate this such that the exponentials get factored, so

C1 Exp[a1]Exp[b1 x] + C2 Exp[a2]Exp[b2 x] + C3 Exp[a3]Exp[b3 x] + ...

Then I would like to combine terms of which b are equal, so for instance if we have b3=b2 then I would like to get

C1 Exp[a1]Exp[b1 x] + (C2 Exp[a2] + C3 Exp[a3]) Exp[b2 x] + ...

Now for each term (identified by unique values of b), I would like to get lists of coefficients and exponential terms, so

{C1 Exp[a1], C2 Exp[a2] + C3 Exp[a3]}

and

{b1, b2}.

For the latter, I think I can use Collect and simplify coefficients of functions (Exp[a x])

But how to get to C1 Exp[a1]Exp[b1 x] + (C2 Exp[a2] + C3 Exp[a3]) Exp[b2 x] + ...?

I looked at using Factor[] for factoring out Exp[a1+b1 x] to Exp[a1]Exp[b1 x]. I also considered using FourierTransform[] but that doesn't work either. It gives me a a sum of DiracDelta[]'s but then I still have the same problem.

Kind regards

Boudewijn Verhaar

============

EDIT:

I think I found an answer myself already. But it doesn't work flawlessly.

First, a case where it does work. I define my input expression:

blah = funcC1[x, y, z] Exp[funca1[x, y, z] + I funcb1[x, y, z] t] + funcC2[x, y, z] Exp[funca2[x, y, z] + I funcb2[x, y, z] t] + funcC3[x, y, z] Exp[funca3[x, y, z] + I funcb2[x, y, z] t]

Then I apply

ft = FourierTransform[blah, t, omg]

ft = Collect[ft, DiracDelta[__]]

divideBySqrt2Pi[x_] := Simplify[x/Sqrt[2 Pi]]

ampls = Map[divideBySqrt2Pi, Cases[ft, a_ DiracDelta[b_] -> a]]

diracArgs = Cases[ft, a_ DiracDelta[b_] -> b];

fromDiracArgToFreq[x_] := x - omg

freqs = Map[fromDiracArgToFreq, diracArgs]

This gives me the desired outcome, for ampls:

{E^funca1[x, y, z] funcC1[x, y, z], E^funca2[x, y, z] funcC2[x, y, z] + E^funca3[x, y, z] funcC3[x, y, z]}

and for freqs:

{funcb1[x, y, z], funcb2[x, y, z]}

But if I use as input only the first term

blah = funcC1[x, y, z] Exp[funca1[x, y, z] + I funcb1[x, y, z] t]

Then both statements involving Cases[ft, ...] yield empty lists. And I don't understand why, because the pattern is there.

$\endgroup$
4
  • $\begingroup$ Cases looks at parts inside the expression. When you input only the first term, it matches the pattern as a whole, but parts inside don't. E.g., compare Cases[{a,b,c},a] and Cases[a,a] $\endgroup$ Commented Dec 3, 2025 at 22:37
  • $\begingroup$ Note that Exp[a1]Exp[b1 x] autosimplifies to E^(a1 + b1 x). I don't think there's a way to do exactly what you want. However, if it's a question formatting output, there are things one can do to hold the factors (e.g. HoldForm[] or Inactive[Exp][...]) and keep the autosimplification from happening. That tends to mess up computations down the line, if not handled carefully. $\endgroup$ Commented Dec 4, 2025 at 1:54
  • $\begingroup$ Using Maple, expand command works on this. But in Mathematica Expand did not do the same. Here is screen shot i.sstatic.net/6wLlzvBM.png and i.sstatic.net/BHrXh9Nz.png I think Maple's expand worked better here. $\endgroup$ Commented Dec 5, 2025 at 17:52
  • 1
    $\begingroup$ Related: (39040), (126905), (245846). The method I used in the last link works on your example. $\endgroup$ Commented Dec 6, 2025 at 18:21

3 Answers 3

4
$\begingroup$

How about using RuleDelayed like this? Here, W is a dummy wrapper, and it is assumed that all the exponents are linear functions of the variable $x$.

Clear["Global`*"];

rule1 = Power[E, func_] :> Exp[func /. x -> 0]*W[Coefficient[func, x]];

rule2 = W[b_] :> Exp[b*x];

SeedRandom[12345];
expr = Sum[
  RandomChoice[{C1, C2, C3}]*
   Exp[RandomChoice[{1, a2, a3}] + RandomChoice[{b1, b2, b3}] x], {20}]

expr

Collect[expr /. rule1, _W] /. rule2

1

$\endgroup$
1
  • $\begingroup$ Thanks! I have to study this, I'm afraid. $\endgroup$ Commented Dec 5, 2025 at 17:13
2
$\begingroup$

This does not give the answer sought in the "EDIT" but it gives the kind of answer asked for in the OP:

blah /. t : Power[E, _] :> 
    Times @@ Power @@@ (FactorList[t] /. s : Power[E, _] :> Hold[s]) //
   Simplify // ReleaseHold
(*
E^(funca1[x, y, z] + I t funcb1[x, y, z]) funcC1[x, y, z] + 
 E^(I t funcb2[x, y, z]) (E^funca2[x, y, z] funcC2[x, y, z] + 
    E^funca3[x, y, z] funcC3[x, y, z])
*)

It does not strike me that the problem is easy. FactorList does break apart exponentials. But if you multiply them again, they recombine in the undesired way. So some kind of trickery with Hold[] or something like it seems necessary to keep the multiplication of two exponentials from combining their exponents. The particular task at hand is something Simplify[] can handle with the held, factored exponentials.

If one uses HoldForm[] instead of Hold[] and omits ReleaseHold[], then output will look like the exponentials have been kept factored. This could be useful if formatting the output was the principal objective.

$\endgroup$
3
  • $\begingroup$ You wrote: FactorList does break apart exponentials. But if you multiply them again, they recombine in the undesired way. $\endgroup$ Commented Dec 5, 2025 at 20:44
  • $\begingroup$ @BoudewijnVerhaar Yes. FactorList[] succeeds by putting the factors in a list, which keeps them from recombining. FactorList[] and Collect[] are more robust and reliable than Cases[] and other pattern-based manipulations. $\endgroup$ Commented Dec 6, 2025 at 0:31
  • $\begingroup$ Ah I see, indeed Cases[] depends more on how Mathematica prefers to manipulate the expressions. But FourierTransform[] transforms A Exp[b+I f0 t] to A Exp[b] DiracDelta[f-f0] which already makes it a lot more robust. So, for now I am helped, but I realize that this is only possible because in my case I f0 t is purely imaginary. If it where purely real, then it is still possible to do this, by substituting t->I imt. But not if there are multiple terms with f0 with differing complex arguments. But perhaps, in that case, a LaPlace transform would help ... But I didn't look at that. $\endgroup$ Commented Dec 6, 2025 at 10:04
1
$\begingroup$

Thanks for all the answers! In the end, I got it to work by enclosing the first input argument of Cases[] in curly brackets {} (so making it a list), and adjusting the levelspec argument of Cases[] to Infinity.

My code:

fromDiracArgToFreq[x_] := Expand[(f //. Solve[x == 0, f][[1]])]
collectDiracDeltaTerms[ft_] := Collect[ft, DiracDelta[__]]
collectExpTerms[x_] := Collect[x, Exp[_], Simplify]

getDiracArgList[ft_] := Cases[{ft}, a_ DiracDelta[b_] -> b, Infinity]
getDiracCoefList[ft_] := Cases[{ft}, a_ DiracDelta[b_] -> a, Infinity]
(*
https://mathematica.stackexchange.com/questions/317162/simplification-of-terms-c-expab-x-to-c-expaexpbx/317163#317163   ;
https://mathematica.stackexchange.com/questions/278163/collect-and-simplify-coefficients-of-functions-expa-x   ;
*)

toFourierTransform[x_] := FourierTransform[x // collectExpTerms, t, f, FourierParameters -> {0, -2 Pi}] // collectDiracDeltaTerms
(*
FourierParameters choice: see https://reference.wolfram.com/language/ref/FourierTransform.html and scroll down to bullet "Common settings for FourierParameters include:"
*)

retrieveFreqs[x_] := Map[fromDiracArgToFreq, toFourierTransform[x] // getDiracArgList]
retrieveAmpls[x_] := toFourierTransform[x] // getDiracCoefList // TrigToExp // Factor

And the two working examples:

blah = funcC1[x, y, z] Exp[funca1[x, y, z] + I 2 Pi funcb1[x, y, z] t] + funcC2[x, y, z] Exp[funca2[x, y, z] + I 2 Pi funcb23[x, y, z] t] + funcC3[x, y, z] Exp[funca3[x, y, z] + I 2 Pi funcb23[x, y, z] t];

retrieveFreqs[blah]
(*
==> {funcb1[x, y, z], funcb23[x, y, z]}
*)

retrieveAmpls[blah]
(*
==> {E^funca1[x, y, z] funcC1[x, y, z], E^funca2[x, y, z] funcC2[x, y, z] + E^funca3[x, y, z] funcC3[x, y, z]}
*)

And

blah = funcC1[x, y, z] Exp[funca1[x, y, z] + I 2 Pi funcb1[x, y, z] t];

retrieveFreqs[blah]
(*
==> {funcb1[x, y, z]}
*)

retrieveAmpls[blah]
(*
==> {E^funca1[x, y, z] funcC1[x, y, z]}
*)
$\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.