6
$\begingroup$

I have an expression: $5e^{13t} = F(e^{14t})$. I want to use Mathematica to determine $F$ on this function to be $F(q) = 5q^{13/14}$. How do I do this? Sorry if this seems trivial -- I can't quite formulate what I need to google it either.

Thanks!

$\endgroup$
1
  • 2
    $\begingroup$ F[E^(14 t)] == 5 E^(13 t) /. (Solve[q == E^(14 t), t][[1]] /. C[1] -> 0) $\endgroup$
    – Bob Hanlon
    Commented Jun 13, 2022 at 5:17

1 Answer 1

8
$\begingroup$

This is actually a tiny bit tricky as far as I'm aware, in that there's not a built-in syntax that "just does it"! Maybe someone's aware of a way Mathematica can easily solve for symbolic functions like this, but I'm not. (Mathematica has built-in syntax to solve for functions in the context of differential equations, but not in this sort of context, I don't think.)

Still, it won't be too difficult. We're going to use a combination of Eliminate, which eliminates variables from a set of equations, and Solve, which solves for an expression. We can write

ClearAll[f,q,t]

sol = Solve[Eliminate[{q == Exp[13 t], f[q] == 5 Exp[14 t]}, t], f[q]]

The answer is a list of lists-of-rules showing us that there are actually multiple solutions for f[q] here, one corresponding to each 13'th root of unity. (We also get a warning that this might not be everything.) We can use these as usual by writing f[q] /. sol, which will give us a list of replacements (one for each list-of-rules).


As a bonus, I wrote a function to do this automatically in the simple case where we have a function of a single variable equal to a function of another variable. I haven't really cleaned up the code, but the bulk of it is just to give the user options on how to use it!

In the normal case, the basic syntax is

SolveFunction[f[argexpr] == expr, f[q], oldvars]
(* or *)
SolveFunction[f[argexpr] == expr, f, oldvars]

Here, oldvars are the variables in argexpr that you want to get rid of, such as t.

We could write our request as

SolveFunction[f[Exp[13 t]] == 5 Exp[14 t], f[q], t]

First, here's a simple version, without all the option-handling bells and whistles, so you can see the core of the definition. This might be all you need.

SimpleSolveFunction[eq : f_[argexpr_] == expr_, f_[arg_], oldargs_] :=
  Solve[Eliminate[{arg == argexpr, f[arg] == expr}, oldargs], f[arg]]

SimpleSolveFunction[f[Exp[13 t]] == 5 Exp[14 t], f[q], t]

Here's how the more-controllable version works.

By default, I had it give a list of functions (and in the case where we specify f instead of f[q] in the arguments, anonymous functions), so that the result is actually usable! However, I also included an option that lets you set what you want the result type to be. Just specify the option "ResultType" as "Functions" (* default *), "Equations", "Rules", "ListOfEqautions", or "Expressions".

Note that when we ask for "Equations", I by-default change the solver form Solve to Reduce. The solver can also be specified independently by the option "Solver".

You can also pass options to Eliminate by specifying a list of options as the value of the option "EliminateOptions", and to the solver by "SolverOptions". This can be useful when passing in assumptions.

Even the more-functional version is by no means polished. Certain capabilities that should be available via Reduce, Solve, and Eliminate aren't yet, we only allow functions of one argument, sometimes these methods fail, and error handling is nonexistent. Still, thought I'd just post this for fun!

Options[SolveFunction] = {"ArgumentName" -> None, 
   "ResultType" -> "Functions", "EliminateOptions" -> {}, 
   "SolverOptions" -> {}, "Solver" -> Automatic};

SolveFunction[eq_, f_[arg_], oldargs_, opts : OptionsPattern[]] := 
 SolveFunction[eq, f, oldargs, "ArgumentName" -> arg, opts]

SolveFunction[eq : f_[argexpr_] == expr_, f_Symbol, 
  oldargs : (_Symbol | {___Symbol}) : {}, OptionsPattern[]] :=
 Module[{q},
  If[OptionValue["ArgumentName"] =!= None, 
   q = OptionValue["ArgumentName"]];
  Switch[OptionValue["ResultType"],
    "Functions",
    (If[OptionValue["ArgumentName"] =!= None, 
        Construct[Function, q, #] &, 
        Construct[Function, # /. {q :> Construct[Slot, 1]}] &] /@ (f[
          q] /. #)) &,
    "Expressions", (f[q] /. #) &,
    "Rules" | "Equations", # &,
    "ListOfEquations", ((f[q] == #) & /@ (f[q] /. #)) &]@
   Switch[{OptionValue["ResultType"], OptionValue["Solver"]},
     {"Equations", Solve}, Or @@ ((f[q] == #) & /@ (f[q] /. #)) &,
     {Except["Equations"], Reduce}, {ToRules[#]} &,
     _, # &]@
    If[OptionValue["Solver"] === Automatic, 
      Switch[OptionValue["ResultType"], "Equations", Reduce, _, Solve],
      OptionValue["Solver"]][
     Eliminate[{f[q] == expr, q == argexpr}, oldargs, 
      Sequence @@ OptionValue["EliminateOptions"]],
     f[q], Sequence @@ OptionValue["SolverOptions"]]
  ]

I haven't fully tested every option combination yet, but here are some examples:

SolveFunction[f[Exp[13 t]] == 5 Exp[14 t], f[q], t, 
 "ResultType" -> "ListOfEquations"]

SolveFunction[f[Exp[13 t]] == 5 Exp[14 t], f[q], t, 
 "ResultType" -> "Equations"]

SolveFunction[f[Exp[13 t]] == 5 Exp[14 t], f[q], t, 
 "ResultType" -> "Rules", "Solver" -> Reduce]

SolveFunction[f[Log[x]] == 5 Exp[x], f[q], x, 
 "ResultType" -> "Expressions", 
 "SolverOptions" -> {Assumptions -> q > 0}]
$\endgroup$
2
  • $\begingroup$ Nice answer, thorimur! :) $\endgroup$ Commented Jun 13, 2022 at 0:47
  • $\begingroup$ @E.Chan-López Thank you! I appreciate it! :) $\endgroup$
    – thorimur
    Commented Jun 14, 2022 at 3:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.