0
$\begingroup$

Using Mathematica, how can we numerically find only complexes, but not real roots, of a function?

For example, if we have f:C->C, and we have roots like, R1,R2,...,Rn (real roots, without imaginary part) and roots like C1,C2,...,Cm (complex roots with the imaginary part), how can we, using FindRoot, NSolve or other mechanisms, avoid finding the R's roots, but find one of the C's roots?

Edit:

My best attempt was like the following (disclaimer, this is not my function, but it has similar issues):

Block[
 {Test, x},
 Test[x_] := (x - Pi) (x - E I) (x - (E + Pi I)) PolyGamma[x];
 NSolve[Test[x] == 0 && Im[x] != 0, x, WorkingPrecision -> 100]
 ]

For the function above I receive the following error:

NSolve::nsmet: This system cannot be solved with the methods available to NSolve.

If I change PolyGamma to Gamma the strategy works, but how can we fix for this function, for example?

$\endgroup$
3
  • 1
    $\begingroup$ it is always better to give an example or two. Otherwise, you are asking the person who is trying to help you to go and find such examples themselves first. But you can always find all roots, and remove the one that are complex if needed. Note that NSolve has Reals domain also you can try. $\endgroup$
    – Nasser
    Jan 6 at 3:50
  • $\begingroup$ @Nasser, I have added now my best attempt. It seems FindRoot has less resources available. $\endgroup$
    – GarouDan
    Jan 6 at 4:18
  • $\begingroup$ For your example, as I said, just call NSolve and remove the solution that contains complex number. Here is screen shot !Mathematica graphics You can easily now remove the complex result. There are many posts in this forum showing how to check result which is complex or not. Why is it important for you that NSolve does this itself, vs. you doing it after obtaining the result? Or if you just want complex roots, and not real ones, you can also do that. $\endgroup$
    – Nasser
    Jan 6 at 4:37

2 Answers 2

3
$\begingroup$

You may use "Select" to pick the complex roots. But note the warning from "NSolve":

Test[x_] := (x - Pi) (x - E I) (x - (E + Pi I)) PolyGamma[x];
Select[ x /. NSolve[Test[x] == 0, x, WorkingPrecision -> 100], 
 Im[#] != 0 &]

{2.7182818284590452353602874713526624977572470936999595749669676277240\
76630353547594571382178525166427 I, 
 2.7182818284590452353602874713526624977572470936999595749669676277240\
76630353547594571382178525166427 + 
  3.141592653589793238462643383279502884197169399375105820974944592307\
816406286208998628034825342117068 I}
$\endgroup$
2
  • $\begingroup$ NSolve[Test[x] == 0 && Re[x] >= -10 && Re[x] <= 10 && Im[x] >= -10 && Im[x] <= 10, x, Complexes] instead of NSolve[Test[x] == 0, x, WorkingPrecision -> 100] produces a better result. $\endgroup$
    – user64494
    Jan 6 at 10:52
  • $\begingroup$ Very interesting technique. It seems my problem is much harder than I thought, even this way NSolve struggles, but the Select strategy is helpful ;) I need to take a better look and return, thanks $\endgroup$
    – GarouDan
    Jan 8 at 17:46
2
$\begingroup$
$Version

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

Clear["Global`*"]

Test[x_] := (x - Pi) (x - E I) (x - (E + Pi I)) PolyGamma[x];

sol = NSolve[
   {Test[x] == 0, -20 < Re[x] < 20, -20 < Im[x] < 20, Im[x] != 0},
   x, WorkingPrecision -> 50] // N

(* {{x -> 0. + 2.71828 I}, {x -> 2.71828 + 3.14159 I}} *)

Verifying the result

{Test[x], Test[x] == 0} /. sol

(* {{0. + 0. I, True}, {0. + 0. I, True}} *)

approx[x_?NumericQ] := If[
   Mod[x + 10^-11, E] < 10.^-10,
   E*RootApproximant[x/E],
   If[Mod[x + 10^-11, Pi] < 10.^-10,
    Pi*RootApproximant[x/Pi], x]];
SetAttributes[approx, Listable]

sol2 = sol /. z_Complex :> approx[ReIm[z]] . {1, I}

(* {{x -> I E}, {x -> E + I π}} *)

This result is exact

{Test[x], Test[x] == 0} /. sol2

(* {{0, True}, {0, True}} *)

EDIT: Alternatively, since Test is a product of factors

sol3 = Solve[{#, Im[x] != 0}, x] & /@
  Thread[(List @@ Test[x]) == 0]

(* Solve::nsmet: This system cannot be solved with the methods available to Solve. Try Reduce or FindInstance instead.

{{{x -> I E}}, {}, {{x -> E + I π}}, 
 Solve[{PolyGamma[0, x] == 0, Im[x] != 0}, x]} *}

The warning only applies to the last factor

NSolve[{PolyGamma[0, x] == 0, Im[x] != 0, -20 < Re[x] < 20, -20 < Im[x] < 20},
  x]

{}
$\endgroup$
1
  • $\begingroup$ Hum, interesting, so if I understood well, if I refine the search interval, what before was considered unsolvable by NSolve is now possible ;) Thanks for this approach. $\endgroup$
    – GarouDan
    Jan 8 at 17:47

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.