I will explain the problem using a very simple toy model of the actual problem at hand which is rather complicated. I am plotting the following

With[{k = 0.1, a = 1}, Plot[1/(a + Sin[x*k]), {x, 0, \[Pi]}]]

which returns me a nice output. Now, I want to supplement the argument with a solution sol[x,k] from outside, so I use Block with regards to the scoping constructs, i.e.,

eq[α_, k_, x_] := Sin[k + α] == x*Cos[k]
sol[x_?NumericQ, k_ /; 0 <= k <= Pi]:= α/.NSolve[{eq[α, k, x], 0 <= α <= Pi}, α, Reals]
Block[{k = 0.1, a = 1}, Plot[1/(a + Sin[x*k + sol[x, k]]), {x, 0, \[Pi]}]]

However, since sol[x,k] has empty solutions at some parameter values, like e.g. sol[1.1,0.1], so e.g., when I plug the solution sol[1.1,k] in the argument of sin inside Block it returns me an empty plot. While, I thought that it should return me the plot which is generated using the code With? i.e., the one without this extra factor in the argument, meaning, with sol[x,k]=0. Is it the correct way of plotting in such situations?. Since there are ranges in x where there is no solution, so does Block or plot know this when plotting for x?
Edit: Let me consider another regime where there are two solutions, take for example sol[0.2,k] which has two solutions and Block[..]plot[..] with sol[0.2,k] gives back the following output enter image description here

But, plugging sol[x,k] inside the argument and Block[..]plot[..] gives enter image description here

  • 1
    $\begingroup$ sol[…] returns a list of solutions, which is what causes the issues (since Plot expects the expression in the first argument to return a single number) $\endgroup$
    – Lukas Lang
    Sep 1 '18 at 8:39
  • $\begingroup$ @LukasLang Thanks, yes this is what I suspected because there are various solutions in different regimes of parameter x, so how to fix this to get the correct output? I edited the question with more information now. $\endgroup$
    – AtoZ
    Sep 1 '18 at 8:54

It is not a trivial problem, as usually Plot can handle multiple solutions as demonstrated above. The problem happens because the number of solutions changes.

There are two simple wokrarounds.

You could just plot First and Last solutions by solving twice:

eq[\[Alpha]_, k_, x_] := Sin[k + \[Alpha]] == x*Cos[k]
sol[x_?NumericQ, k_ /; 0 <= k <= Pi] := \[Alpha] /. 
  NSolve[{eq[\[Alpha], k, x], 0 <= \[Alpha] <= Pi}, \[Alpha], Reals]
Block[{k = 0.1, a = 1},
   1/(a + First@Sin[x*k + sol[x, k]]),
   1/(a + Last@Sin[x*k + sol[x, k]])
   }, {x, 0, \[Pi]},
  PlotStyle -> {Automatic, Dashed}, PlotRange -> All]]

enter image description here

Or you solve once and then sort out your solutions later

First we solve for meany values of x

solutions = 
  Block[{k = 0.1, a = 1}, 
   Table[{x, 1/(a + Sin[x*k + sol[x, k]])}, {x, 0, 1, 0.01}]];

We assume, that there is always at least one solution and we make a list of points we can plot later

solutions1 = {#[[;; , 1]], #[[;; , 2, 1]]}\[Transpose] &@solutions;

Usinging Select we take all the points, where there was at least too solutions and make a list out of the second solution for plotting.

solutions2 = {#[[;; , 1]], #[[;; , 2, 2]]}\[Transpose] &@
   Select[solutions, Length[#[[2]]] > 1 &];

ListLinePlot[{solutions1, solutions2}]

enter image description here

  • $\begingroup$ In the first part of your answer something bad happened when you copied the code. It has all sorts of `\` marks that don't belong there. Try to copy and paste again. $\endgroup$ Sep 1 '18 at 20:05
  • $\begingroup$ @Johu, Thanks. There are however some extra '` marks in your code above. The second code you posted looks very tricky :-) $\endgroup$
    – AtoZ
    Sep 2 '18 at 3:35
  • 1
    $\begingroup$ Sorry of the failed paste. It is now fixed and I added explanations for the second solutions. I think there is no way to get the same task done concisely and using much easier code. I actually learned quite a bit by reading the code of other people at SE. I hope you can also get something from it. $\endgroup$
    – Johu
    Sep 2 '18 at 8:47
  • $\begingroup$ @Johu thanks. One last clarification. If there is say 3 solutions, then with regards to your first code, can we implement First@[sol..], Second@[sol..] , Last@[sol..]? $\endgroup$
    – AtoZ
    Sep 3 '18 at 3:46
  • 1
    $\begingroup$ No, then you need something similar to the second solutions, as Second is not defined if there is only 1 solution. Consider changing your sol, such that it would always give you the same number of solutions, even is some of them are the same. Then everything else is easy. $\endgroup$
    – Johu
    Sep 3 '18 at 11:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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