Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Define Is meromorphic #19306

Merged
merged 5 commits into from May 15, 2020
Merged

Define Is meromorphic #19306

merged 5 commits into from May 15, 2020

Conversation

jksuom
Copy link
Member

@jksuom jksuom commented May 13, 2020

References to other Issues or PRs

See #8320

Brief description of what is fixed or changed

Added a new method, .is_meromorphic(x, a) to check whether an expression is a
meromorphic function of x at a.

Other comments

Limits of meromorphic functions can be easily found from the leading terms of their Laurent
series expansions. There is some heuristic in Limit.doit() for that purpose (if all(ok(w) ...))
but in most cases the limit will be handled by gruntz. That will make a change of variables
introducing an essential singularity and consequently increasing the difficulty of finding a limit.

This method can be used to cover most cases where the limit can be found from the leading
term.

Release Notes

  • core
    • expr: A new method is_meromorphic is added.

Sums and products of meromorphic functions are meromorphic. This
implementation returns True if all terms of a sum or factors of a
product are meromorphic, and False if exactly one term or factor is
not meromorphic. Otherwise it returns None as the singularities of
several functions may cancel.
There are two kinds of powers that are meromorphic. If the exponent
is an integer, then the power is meromorphic if and only if the
base is meromorphic. More generally, a power is meromorphic if both
base and exponent are meromorphic and finite and, in addition, base
is nonzero.
Most functions defined in SymPy are meromorphic with a few essential
singularities or branch points. A private attribute, ``_singularities``,
is added to function classes. For meromorphic functions, it is a finite
iterator that contains the essential singularities and branch points.
It may also be ``True``, ``False`` or ``None``, in which case it will
be the return value of ``is_meromorphic``.
@sympy-bot
Copy link

sympy-bot commented May 13, 2020

Hi, I am the SymPy bot (v158). I'm here to help you write a release notes entry. Please read the guide on how to write release notes.

Your release notes are in good order.

Here is what the release notes will look like:

  • core
    • expr: A new method is_meromorphic is added. (#19306 by @jksuom)

This will be added to https://github.com/sympy/sympy/wiki/Release-Notes-for-1.7.

Note: This comment will be updated with the latest check if you edit the pull request. You need to reload the page to see it.

Click here to see the pull request description that was parsed.

<!-- Your title above should be a short description of what
was changed. Do not include the issue number in the title. -->

#### References to other Issues or PRs
<!-- If this pull request fixes an issue, write "Fixes #NNNN" in that exact
format, e.g. "Fixes #1234" (see
https://tinyurl.com/auto-closing for more information). Also, please
write a comment on that issue linking back to this pull request once it is
open. -->
See #8320

#### Brief description of what is fixed or changed
Added a new method, `.is_meromorphic(x, a)` to check whether an expression is a
meromorphic function of `x` at `a`.


#### Other comments
Limits of meromorphic functions can be easily found from the leading terms of their Laurent
series expansions. There is some heuristic in `Limit.doit()` for that purpose (`if all(ok(w) ...)`)
but in most cases the limit will be handled by `gruntz`. That will make a change of variables
introducing an essential singularity and consequently increasing the difficulty of finding a limit.

This method can be used to cover most cases where the limit can be found from the leading
term.

#### Release Notes

<!-- Write the release notes for this release below. See
https://github.com/sympy/sympy/wiki/Writing-Release-Notes for more information
on how to write release notes. The bot will check your release notes
automatically to see if they are formatted correctly. -->

<!-- BEGIN RELEASE NOTES -->
* core
    * expr: A new method `is_meromorphic` is added.
<!-- END RELEASE NOTES -->

Update

The release notes on the wiki have been updated.

@oscarbenjamin
Copy link
Contributor

This looks useful but I wonder if it should be a method on all of Expr firstly because there are too many methods on Expr but also because I'm not sure it can make sense for all of Expr e.g.:

In [1]: M = MatrixSymbol('M', 2, 2)                                                                                               

In [2]: M.is_meromorphic(x, 0)                                                                                                    
Out[2]: True

Maybe is_complex should be checked in the default handler (that doesn't include zoo though).

@jksuom
Copy link
Member Author

jksuom commented May 13, 2020

Maybe is_complex could be added though matrix-valued functions can also be meromorphic.
Compare:

In [1]: M = MatrixSymbol('M', 2, 2)

In [2]: M.is_rational_function(x)
Out[2]: True

@codecov
Copy link

codecov bot commented May 13, 2020

Codecov Report

Merging #19306 into master will decrease coverage by 4.212%.
The diff coverage is 80.303%.

@@              Coverage Diff              @@
##            master    #19306       +/-   ##
=============================================
- Coverage   75.595%   71.382%   -4.213%     
=============================================
  Files          651       651               
  Lines       169536    169483       -53     
  Branches     40015     39988       -27     
=============================================
- Hits        128161    120981     -7180     
- Misses       35755     42754     +6999     
- Partials      5620      5748      +128     

@oscarbenjamin
Copy link
Contributor

Is this correct?

In [23]: sqrt(x).is_meromorphic(x, -1)                                                                                            
Out[23]: True

@jksuom
Copy link
Member Author

jksuom commented May 14, 2020

Yes, the two branches of sqrt are meromorphic everywhere except at the origin. The Taylor series at -1 is the one having constant term I. It can be used to find the limit at -1.

@oscarbenjamin
Copy link
Contributor

Is this correct:

In [14]: x = Symbol('x', real=True)                                                                                               

In [15]: sqrt(-1 +I*x).limit(x, 0)                                                                                                
Out[15]: ⅈ

In [16]: sqrt(-1 +I*x).limit(x, 0, '+')                                                                                           
Out[16]: ⅈ

In [17]: sqrt(-1 +I*x).limit(x, 0, '-')                                                                                           
Out[17]: ⅈ

In [18]: sqrt(-1 + I*1e-10).n()                                                                                                   
Out[18]: 5.0e-11 + 1.0ⅈ

In [19]: sqrt(-1 - I*1e-10).n()                                                                                                   
Out[19]: 5.0e-11 - 1.0

Should the limit not be different in the two directions approaching the branch cut?

@jksuom
Copy link
Member Author

jksuom commented May 14, 2020

Should the limit not be different in the two directions approaching the branch cut?

That is something that limit should handle. Another method would probably be needed to see if something lands on a branch cut.

@oscarbenjamin
Copy link
Contributor

I guess I don't really understand what meromorphic means if the sqrt function defined in this way can be meromorphic on the negative reals. Wikipedia says:

In the mathematical field of complex analysis, a meromorphic function on an
open subset D of the complex plane is a function that is holomorphic on all
of D except for a set of isolated points, which are poles of the function

https://en.wikipedia.org/wiki/Meromorphic_function

Here we talk about being meromorphic at a point which presumably means in a neighbourhood of that point so f(z) is meromorphic "in z at a" if there is an open subset of the complex plane containing a within which f(z) is holomorphic except at isolated points.

The sqrt(z) function as defined in sympy is discontinuous and therefore not holomorphic along the whole negative real axis. It seems to me that an open set around any point on the negative axis will contain an open interval of the real line along which sqrt(z) is not holomorphic.

@jksuom
Copy link
Member Author

jksuom commented May 14, 2020

I am used to consider multivalued functions meromorphic at point if all its branches are meromorphic. Some mechanism should be implemented for choosing the branch at a branch cut. I have made an attempt towards that in #14715. Some methods like _eval_nseries of functions should probably need the ability to make the proper choice at a branch cut.

@oscarbenjamin
Copy link
Contributor

Perhaps a definition of meromorphic could be given in the docstring with the sqrt(z) example to illustrate what it means.

@jksuom
Copy link
Member Author

jksuom commented May 14, 2020

That looks like a good idea.

@oscarbenjamin
Copy link
Contributor

Looks good to me

@oscarbenjamin oscarbenjamin merged commit 1f5a725 into sympy:master May 15, 2020
@jksuom
Copy link
Member Author

jksuom commented May 15, 2020

Thanks, @oscarbenjamin

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants