2
$\begingroup$

When I solve a system of equations with Reduce, it will give me as possibilities that system parameters can be exactly some special value that will allow the variables of interest to be something weird.

In my experimental science setting, these solutions are irrelevant. How do I remove them from my expression?

For reference, here's my scenario

Here's the solution that Mathematica gives me:

sol = (ez != 0 && (nr == Sqrt[ϵc] || 
     nr + Sqrt[ϵc] == 
      0) && ((ex == 0 && 
       ey == 0 && ϵa^2 + ϵb^2 != ϵa \
ϵc) || (ex ϵa == 
        ey ϵb && (2 ϵa + 
           Sqrt[-4 ϵb^2 + ϵc^2] == ϵc || \
ϵc + Sqrt[-4 ϵb^2 + ϵc^2] == 
          2 ϵa)))) || (ex ϵa == 
    ey ϵb && ((ex != 
        0 && (2 ϵa + 
           Sqrt[-4 ϵb^2 + ϵc^2] == ϵc || \
ϵc + Sqrt[-4 ϵb^2 + ϵc^2] == 
          2 ϵa) && (nr == Sqrt[ϵc] || 
         nr + Sqrt[ϵc] == 0)) || (ey != 0 && 
       ez == 0 && (nr == Sqrt[ey ϵa + ex ϵb]/Sqrt[
          ey] || nr + Sqrt[ey ϵa + ex ϵb]/Sqrt[
           ey] == 0))))

or visualized:

tree of solutions

Any expression that solely relates the ϵ parameters to each other is a non-physical situation. Going through this tree by hand, I can reduce it to two cases.

  1. ez nonzero, ex=ey=0, and $n_r = \pm \sqrt{\epsilon_c}$
  2. ez = 0, $ e_x=e_y \epsilon_b/\epsilon_a $ and n_r = expression

I have more complicated expressions for which it would be painful to do this by hand. How can I do filter such irrelevant solutions automatically with code?

Update 20230831

@Alexei Boulbitch: here is the additional background you requested:

The equation I am solving is light propagation in a magnetic medium. Explicitly,

In[32]:= $Assumptions = {(θ|ϕ)∈Reals, 0<θ<π,  0<ϕ<2π ,ϵa!=0,ϵb !=0, ϵc != 0, ex != 0 || ey!=0 || ez!=0};
In[33]:= n = nr { Sin[θ] * Cos[ϕ],  Sin[θ] * Sin[ϕ],  Cos[θ]} ;
e = {ex,ey,ez};
ϵr  = {
{ϵa,-ϵb,0},
{ϵb,ϵa,0},
{0,0,ϵc}
};
In[36]:= eqn = n (n.e) - e (n.n) + ϵr. e == {0,0,0};
In[44]:= divCondition = n.ϵr.e == 0;

I'm looking for ex, ey, ez, nr that satisfy eqn and divCondition.

I care about this solution for particular values of θ and ϕ. Explicitly,

Solve[{eqn , divCondition} /. θ -> π/2 /. ϕ -> 0, {ex,ey, ez, nr}]

Solve however gives me:

Not all solutions

Which is why instead I did:

sol = Reduce[
  {
    eqn ,
    divCondition,
    ex != 0 || ey != 0 || ez != 0
    } /. { θ -> π/2, ϕ -> 0}
  , {ex, ey, ez, nr}] // FullSimplify 

The result of this Reduce is what I gave you.

Note, the result of Solve was almost exactly what I was looking for, but it was not obvious to me what solutions it was dropping. Is there a reason not to use Reduce?

$\endgroup$
4
  • $\begingroup$ It would be helpful if you post not only the solution but also the equation you are solving. Nevertheless, have you any special reasons to use Reduce, rather than Solve? $\endgroup$ Aug 31, 2023 at 21:08
  • $\begingroup$ This does not automatically discard all the cases that you wish to ignore, but does LogicalExpand make it easier and more obvious which cases you wish to ignore? $\endgroup$
    – Bill
    Aug 31, 2023 at 21:53
  • $\begingroup$ @AlexeiBoulbitch I updated my question with the info you requested. $\endgroup$
    – ions me
    Sep 1, 2023 at 1:21
  • $\begingroup$ Thanks @Bill, wish I new about LogicalExpand before. $\endgroup$
    – ions me
    Sep 1, 2023 at 1:24

2 Answers 2

1
$\begingroup$
$Version

(* "13.3.1 for Mac OS X ARM (64-bit) (July 24, 2023)" *)

Clear["Global`*"]

My result is different from what you expect, but perhaps I misunderstand your intent.

sol = (ez != 
      0 && (nr == Sqrt[ϵc] || 
       nr + Sqrt[ϵc] == 
        0) && ((ex == 0 && 
         ey == 0 && ϵa^2 + ϵb^2 != ϵa ϵc) || (ex ϵa == 
          ey ϵb && (2 ϵa + 
             Sqrt[-4 ϵb^2 + ϵc^2] == ϵc || ϵc + Sqrt[-4 ϵb^2 + ϵc^2] == 
            2 ϵa)))) || (ex ϵa == 
      ey ϵb && ((ex != 
          0 && (2 ϵa + 
             Sqrt[-4 ϵb^2 + ϵc^2] == ϵc || ϵc + Sqrt[-4 ϵb^2 + ϵc^2] == 
            2 ϵa) && (nr == Sqrt[ϵc] || 
           nr + Sqrt[ϵc] == 0)) || (ey != 0 && 
         ez == 0 && (nr == Sqrt[ey ϵa + ex ϵb]/Sqrt[ey] || 
           nr + Sqrt[ey ϵa + ex ϵb]/Sqrt[ey] == 0))));

onlyϵ[expr_] := Union[Variables[
    Level[expr, {-1}]], {ϵa, ϵb, ϵc}] === {ϵa, ϵb, ϵc}

((sol // LogicalExpand) /. {
    Or[expr1___, expr2_?onlyϵ] :> expr1,
    And[expr1___, expr2_?onlyϵ] :> False}) // Simplify

(* ey != 0 && ez == 0 && 
 ex ϵa == 
  ey ϵb && (nr == Sqrt[ey ϵa + ex ϵb]/Sqrt[ey] || 
   nr + Sqrt[ey ϵa + ex ϵb]/Sqrt[ey] == 0) *)

EDIT: If you intend that And[expr1__, expr2_?onlyϵ] :> expr1 rather than And[expr1__, expr2_?onlyϵ] :> False then

((sol // LogicalExpand) /. {Or[expr1__, expr2_?onlyϵ] :> expr1, 
    And[expr1__, expr2_?onlyϵ] :> expr1}) // Simplify

(* ex == 0 || ey == 0 || 
 ez != 0 || (ex ϵa == 
    ey ϵb && (nr == Sqrt[ey ϵa + ex ϵb]/Sqrt[ey] ||
      nr + Sqrt[ey ϵa + ex ϵb]/Sqrt[ey] == 0)) || 
 nr + Sqrt[ϵc] == 0 || nr == Sqrt[ϵc] *)
$\endgroup$
4
  • $\begingroup$ By the way, how do you get [epsilon] to render in your post? As for the output, when I run your code, I get what you got, which is exactly line 2 of what I did by hand in my main post. However, it does not give me line 1 of what I simplified by hand. $\endgroup$
    – ions me
    Sep 1, 2023 at 1:32
  • 2
    $\begingroup$ See Additional useful buttons for our M.SE editor $\endgroup$
    – Bob Hanlon
    Sep 1, 2023 at 1:41
  • $\begingroup$ Looking at my tree diagram, you code properly dealt with the branch going upwards from the root or, however it completely discarded the branch going downwards. I can't figure out why it deleted that branch. $\endgroup$
    – ions me
    Sep 1, 2023 at 2:34
  • $\begingroup$ onlyϵ[expr_] := Union[Variables[ Level[expr, {-1}]], {ϵa, ϵb, ϵc}] === \ {ϵa, ϵb, ϵc} If I replace your last line with goodSol = sol /. Equal[expr1_?onlyϵ, expr2_?onlyϵ] :> False ; It does exactly what I want. $\endgroup$
    – ions me
    Sep 1, 2023 at 3:01
1
$\begingroup$

There are two things. First, the structure of your system of equations seems to be not recognizable by Solve but is recognizable by Reduce. The tip is to transform them into the classical form:

equations = 
 Join[Map[Equal[#, 0] &, 
     n (n . e) - 
      e (n . n) + ϵr . 
       e], {divCondition}] /. θ -> π/2 /. ϕ -> 0

(*  {ex ϵa - ey ϵb == 
  0, -ey nr^2 + ey ϵa + ex ϵb == 
  0, -ez nr^2 + ez ϵc == 0, 
 ex nr ϵa - ey nr ϵb == 0}  *)

Now, one can solve it using Solve:

Solve[equations, {ex, ey, ez, nr}]

(*Solve::svars: Equations may not give solutions for all "solve" variables.*)

(*  {{ex -> (ey ϵb)/ϵa, ez -> 0, 
  nr -> -(Sqrt[ϵa^2 + ϵb^2]/
    Sqrt[ϵa])}, {ex -> (ey ϵb)/ϵa, ez -> 0,
   nr -> Sqrt[ϵa^2 + ϵb^2]/
   Sqrt[ϵa]}, {ex -> 0, ey -> 0, 
  nr -> -Sqrt[ϵc]}, {ex -> 0, ey -> 0, 
  nr -> Sqrt[ϵc]}}  *)

The second thing is that there is the warning: "Solve::svars: Equations may not give solutions for all "solve" variables."

It is standard in the case you are solving nonlinear equations with a certain complexity.

In fact, it means that, in principle, there could be other solutions, but not necessarily. If you have other ways to check, then check it. If you have already obtained all solutions that make sense, it is probably OK. It depends on the problem one is solving.

Hope it helps.

$\endgroup$

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.