0
$\begingroup$

I have a complicated expression that contains N variables.

I want to create a function of N-1 that solves for one of those variables

Toy example:

expr = a^2-Sin[a*b]
astar[b_] := NSolve[expr==0, a, Reals]
astar[1]

does not work. I hoped it was equivalent to

NSolve[(expr/.{b->1})==0,a, Reals]

which does work.

I also tried

expr = a^2-Sin[a*b]
astar[b_] := NSolve[(expr/.{b->b})==0, a, Reals]
astar[1]

but that also doesn't work.

$\endgroup$
3
  • $\begingroup$ astar[v_] := NSolve[(expr /. b -> v) == 0, a, Reals] works - your b->b didn't work because that will become 1->1 due to evaluation order. $\endgroup$
    – flinty
    Commented Jun 6, 2020 at 15:43
  • $\begingroup$ @flinty Okay, duh. I tried that final paragraph while writing the question but I guess I didn't do that seriously enough and had already decided I need help. Sorry about that. But still, is that the canonical way to do what I want to do? $\endgroup$
    – Bananach
    Commented Jun 6, 2020 at 15:58
  • $\begingroup$ No idea. It does the job. $\endgroup$
    – flinty
    Commented Jun 6, 2020 at 16:11

1 Answer 1

1
$\begingroup$

Functions should have explicit parameters.

expr[a_, b_] = a^2 - Sin[a*b];

Functions that use numeric techniques should restrict their parameters to numeric values.

astar[b_?NumericQ] := NSolve[expr[a, b] == 0, a, Reals];

astar[1]

(* {{a -> 0.}, {a -> 0.876726}} *)

Alternatively, get the exact solution

astar2[b_] := Solve[expr[a, b] == 0, a, Reals];

The exact solution is expressed as a Root expression

(* {{a -> 0}, 
   {a -> Root[{-Sin[#1] + #1^2 & , 
     0.8767262153950624459721623939201240\
      4608`20.315993684930827}]}} *)

Its approximate numeric value is the same as provided by astar

% // N

(* {{a -> 0.}, {a -> 0.876726}} *)
$\endgroup$
4
  • $\begingroup$ I don't type the epxression myself, it's the result of something like sol = p[x]/.DSolve[a*p''[x] + b*p[x]+c+d*Sin[e*x], p, x] . Is it really cleanest to convert this into expr[xx_, aa_, bb_, cc_, dd_, ee_] = sol /. {a->aa, b->bb, c->cc, d->dd} first? $\endgroup$
    – Bananach
    Commented Jun 6, 2020 at 18:15
  • $\begingroup$ Thanks for the good practices by the way. You recognized correctly that I have no idea what I'm doing $\endgroup$
    – Bananach
    Commented Jun 6, 2020 at 18:17
  • $\begingroup$ By not specifying initial conditions you have two additional parameters. Making replacements is not necessary; using Set, the RHS will be evaluated immediately. expr[x_, a_, b_, c_, d_, e_, p0_, pp0_] = DSolveValue[{a*p''[x] + b*p[x] + c + d*Sin[e*x] == 0, p[0] == p0, p'[0] == pp0}, p, x] // Simplify $\endgroup$
    – Bob Hanlon
    Commented Jun 6, 2020 at 18:39
  • $\begingroup$ @Bananach, I just wanted to add some emphasis to BobHanlon's answer to make sure the point wasn't lost. The typing is tangential to the main point. The replacement strategy is just winding yourself around an axle. The main point here is that MMA uses an expression-rewriting model of computation. This, expr[a_, b_] := a^2 - Sin[a*b], tells you how expr[x,y] will be rewritten regardless of what x & y are. In particular, they can be symbols. And this, astar2[b_] := Solve[expr[a, b] == 0, a, Reals], shows that this style allows you to leverage composition. $\endgroup$
    – lericr
    Commented Feb 26, 2022 at 19:31

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.