3
$\begingroup$

I am new to Mathematica and I have to select the elements in an array that only contain real numbers and eliminate the ones that have complex parts. Basically the code that I have is an array of possible combinations of too variables c2l and c2h, so that they are the solution to a system of equations. The second part of my question is how to store just the real solutions in a new iobject. Thanks!

$\endgroup$
7
  • $\begingroup$ This can be achieved in a few different ways. Look up e.g. Cases, DeleteCases, and Select in the help files. $\endgroup$ – MarcoB Sep 9 '15 at 22:07
  • $\begingroup$ how do I use Cases with an array though? $\endgroup$ – Jmb Sep 9 '15 at 22:11
  • $\begingroup$ Try e.g. Cases[yourarray, _Real] to select only the real numbers; or alternatively DeleteCases[yourarray, _Complex] to remove the complex entries: the results should be the same if the array only contains numbers. These will work if you have a flat list of numbers; otherwise you might want to add a level specification or a more specific pattern. You will need to show us a sample of your data to get a better answer. $\endgroup$ – MarcoB Sep 9 '15 at 22:14
  • $\begingroup$ This is my array. It is composed by sets of solutions, so that the total length is 36 entries: solsc2lc2hAll = Join[solsc2lc2h1, solsc2lc2h2, solsc2lc2h3, solsc2lc2h4, solsc2lc2h5]//DeleteDuplicates;. A sample of the output it returns is: solsc2lc2hAll [[1]] returns {c2l -> 1, c2h -> 1}. Now, some of these c2h and c2kl are complex and I need to descard them, how can I make Mathematica read it? $\endgroup$ – Jmb Sep 9 '15 at 22:37
  • $\begingroup$ Do you want to retain the Rule structure (i.e. c2l -> 1) or do you just want the values? $\endgroup$ – MarcoB Sep 9 '15 at 22:42
5
$\begingroup$

Consider the solutions to the following equation:

yoursolutions = {x, y} /. NSolve[{x^3 - y^3 == 2, x y == 3} , {x, y}]
{{-0.923042 + 1.59876 I, -0.812531 - 1.40734 I}, 
 {-0.923042 - 1.59876 I, -0.812531 + 1.40734 I}, 
 {0.812531 + 1.40734 I, 0.923042 - 1.59876 I}, 
 {0.812531 - 1.40734 I, 0.923042 + 1.59876 I}, 
 {1.84608, 1.62506}, {-1.62506, -1.84608}}

Now let's use Cases to extract only the real solutions:

onlyrealsols = Cases[yoursolutions, {__Real}]
{{1.84608, 1.62506}, {-1.62506, -1.84608}}

UPDATE: Here is a second version that retains the Rule structure:

solutionrules = NSolve[{x^3 - y^3 == 2, x y == 3} , {x, y}]
{{x -> -0.923042 + 1.59876 I, y -> -0.812531 - 1.40734 I}, 
 {x -> -0.923042 - 1.59876 I, y -> -0.812531 + 1.40734 I}, 
 {x -> 0.812531 + 1.40734 I, y -> 0.923042 - 1.59876 I},
 {x -> 0.812531 - 1.40734 I, y -> 0.923042 + 1.59876 I}, 
 {x -> 1.84608,  y -> 1.62506}, {x -> -1.62506, y -> -1.84608}}

Again, we can use a modified pattern in Cases to select those rules corresponding to real solutions:

realsolutionrules = Cases[
    solutionrules,
    {_ -> solx_, _ -> soly_} /; {solx, soly} \[Element] Reals
  ]
{{x -> 1.84608, y -> 1.62506}, {x -> -1.62506, y -> -1.84608}}
$\endgroup$
5
  • $\begingroup$ It is not working... I think my problem is that the elements in the array are associations, such as {c2l -> 1, c2h -> 1}. So when I have something like '{c2l -> 0.764706, c2h -> 0.764706 + 1.58207*10^-14 I}` it is not deleting when I use DeleteCases[solsc2lc2hAll], _Complex] it still comes up in the output $\endgroup$ – Jmb Sep 9 '15 at 22:48
  • $\begingroup$ Does that make sense? $\endgroup$ – Jmb Sep 9 '15 at 22:49
  • $\begingroup$ @Jmb It does. The question is, do you want to retain the Rule (->) structure, or do you just care about the values? If you care about the values, see how I extracted the values from the rules produced by NSolve in my example above. $\endgroup$ – MarcoB Sep 9 '15 at 22:54
  • $\begingroup$ I need to retain the Rule structure, because I need to plug in these solutions on another set of equations... How can I do this? $\endgroup$ – Jmb Sep 9 '15 at 22:56
  • $\begingroup$ @Jmb OK take a look at the updated version of my answer. $\endgroup$ – MarcoB Sep 9 '15 at 23:18
2
$\begingroup$

You can also use Position and Extract with Repeated for your pattern.

Starting with @MarcoB solutions.

sol = NSolve[{x^3 - y^3 == 2, x y == 3}, {x, y}]
(*
{{x -> -0.923042 + 1.59876 I, y -> -0.812531 - 1.40734 I}, 
 {x -> -0.923042 - 1.59876 I, y -> -0.812531 + 1.40734 I}, 
 {x -> 0.812531 + 1.40734 I, y -> 0.923042 - 1.59876 I}, 
 {x -> 0.812531 - 1.40734 I, y -> 0.923042 + 1.59876 I}, 
 {x -> 1.84608, y -> 1.62506}, 
 {x -> -1.62506, y -> -1.84608}}
*)

We are looking for a Repeated (..) pattern of a Symbol to Real Rule. A pattern for this is (_Symbol -> _Real)... The parenthesis group parts together so Mma knows which part to repeat. You can also tell Repeated exactly how many times to repeat but one or more is fine for this case.

realPos = Position[sol, {(_Symbol -> _Real) ..}, 1]
(* {{5}, {6}} *)

The pattern in Position gives the locations in sol that match that pattern. This can also be done for Complex numbers.

complexPos = Position[sol, {(_Symbol -> _Complex) ..}, 1]
(* {{1}, {2}, {3}, {4}} *)

Extract takes the list of positions and returns the elements in the list.

Extract[sol, realPos]
(* {{x -> 1.84608, y -> 1.62506}, {x -> -1.62506, y -> -1.84608}} *)

Extract[sol, complexPos]
(*
{{x -> -0.923042 + 1.59876 I, y -> -0.812531 - 1.40734 I}, 
 {x -> -0.923042 - 1.59876 I, y -> -0.812531 + 1.40734 I}, 
 {x -> 0.812531 + 1.40734 I, y -> 0.923042 - 1.59876 I}, 
 {x -> 0.812531 - 1.40734 I, y -> 0.923042 + 1.59876 I}}
*)

Hope this helps.

$\endgroup$
2
$\begingroup$

Maybe the simplest solution is adding the option Reals in NSolve directly. For instance,

NSolve[{x^3 - y^3 == 2, x y == 3}, {x, y}, Reals]
{{x -> 1.84608, y -> 1.62506}, {x -> -1.62506, y -> -1.84608}}
$\endgroup$

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.