-
Notifications
You must be signed in to change notification settings - Fork 74
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
Abstracting Polynomials #179
Conversation
…with Polynomial type
At this point all of the existing implementation is re-written and properly deprecated. |
…with Polynomial type
@jverzani Something like For many (typically academic) applications of Edit: Seems like SymPy has this functionality: |
I'm sorry @olof3, I think I misread your comments. You are talking about two things, right:
|
Preface: I don't have any academic knowledge of advanced polynomials and my only previous usage has been with the numpy.polynomials package.
other comments |
Im not sure about roots=[...] or using a flag, as in roots=true. The
latter allows the order of values, symbol without using names. It might
also open up specifying other basis by name. Thoughts?
I’d leave the default fit. I think that’s a documentation fix, if it is
needed.
I prefer integrate (a verb) and only one name for both the definite and
indefinite integral. Much better to use dispatch for the two cases. I also
prefer diff which sounds like a verb. Matching SymPy is my preference.
I also think how you handle the Poly case through the framework is much
better than my suggestion to make Poly{T} an abstract super type.
Have you had time to benchmark? If not, I’ll do some, but not until the new
year.
On Sun, Dec 22, 2019 at 10:50 PM Miles Lucas ***@***.***> wrote:
Preface: I don't have any academic knowledge of advanced polynomials and
my only previous usage has been with the numpy.polynomials package.
-
The ChebyshevT type is based in this wikipedia entry
<https://en.wikipedia.org/wiki/Chebyshev_polynomials#First_kind> and this
numpy implementation
<https://docs.scipy.org/doc/numpy/reference/routines.polynomials.chebyshev.html>.
The exigence for creating this abstract implementation was to better
accommodate having different types of polynomials (eg ChebyshevT are not
defined in any other package as far as I could see when I looked a few
months ago).
-
Polynomial(;roots=) looks good semantically, but it will require a few
extra lines to enable usage like Polynomial{Float64}(roots=Float32[1,
2, 3]).
-
I have no problem removing the default definition for fit; my overall
approach was to default everything to Polynomial.
-
The default order for fit existed before I rewrote the code
-
I originally chose integral over integrate because integral seems less
surprising to return another AbstractPolynomial whereas integrate
ought to return a scalar. Mathematica, does this, I don't know about other
examples. derivative matches the grammar, no other reason.
*other comments*
Again, I wanted to try and create a framework that allows us to start to
have more coverage of polynomial types like in numpy. This is important
because if people are trying to switch from Python, they will regard a
JuliaMath repo as reliable, but will be unsatisfied if a certain type is
not available in Julia. I also feel like it is easier to keep these types
within the single Polynomials.jl package, because the end-user interface
is extremely similar for all of them and after initial implementation I
don't see how there would be much need for independent and parallel
development of different types.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#179?email_source=notifications&email_token=AADG6TESUJNZGCOLCTEFQJTQ2AYPTA5CNFSM4I45Z422YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEHQEBLQ#issuecomment-568344750>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AADG6TFKR7D2ABPSTGZEQFTQ2AYPTANCNFSM4I45Z42Q>
.
--
John Verzani
Department of Mathematics
College of Staten Island, CUNY
verzani@math.csi.cuny.edu
|
Hm, I don't really like I'll go ahead and make changes to I haven't done any benchmarks. I can write some basic ones up. What do you think of these-
I can put these into a |
Also, in terms of breaking builds, I've made sure every single previous test still passes. Fortunately, this ensures we maintain full coverage in our testing. Unfortunately, that means we can only be as sure about not breaking as our unit tests are. I've also made sure that things like |
@jverzani Base exports E: I've left it at derivative now, my first attempt to duck caused a bunch of wacky test failures |
@mileslucas Have you checked out https://github.com/JuliaApproximation/ and in particular https://github.com/JuliaApproximation/ApproxFunOrthogonalPolynomials.jl "This package implements orthogonal polynomial based spaces to ApproxFun, including Chebyshev, Jacobi, Laguerre, and Hermite.".
For packages that include |
This means the only value we’re adding is a simpler interface for directly manipulating series and fitting arbitrary data. In terms of lightening the package, I truly don’t think having the orthogonal polynomials in here will bloat the package. Each implementation is going to around 300 lines of code or fewer, and the common interface makes it easier to keep things consistent. At most, I’d consider making three repos: AbstractPolynomials.jl, Polynomials.jl, SpecialPolynomials.jl, which takes the current organizational structure but streamlines the Polynomials.jl package. The trade-off is 3x more organizational and logistical work by devs. |
So if we decide to not include the special polynomials then 90% of this rewrite is moot, since there’s no sense in having an abstract type for only one concrete subtype. I have no issues with scrapping this, so don’t feel like my sunk time should influence this decision. What do you both think |
I'm not sure what most sensible approach is. I think it could be a good idea if some more people weighed in on this, but perhaps it would be useful to clarify exactly what the questions are. Definitely a number of things that needed fixing, and great that someone got around to do it! I don't see why the Chebyshev expansions can't be in another package if they don't end up in |
Let’s see how many special cases get done, and see if another package is
warranted. It isn’t so hard to split off.
As for diff, we use that in SymPy and having a base function is actually
good, as we do t get name collisions.
As for benchmarks, I was just thinking about comparing to the current
release.
On Mon, Dec 23, 2019 at 4:24 PM olof3 ***@***.***> wrote:
I'm not sure what most sensible approach is. I think it could be a good
idea if some more people weighed in on this, but perhaps it would be useful
to clarify exactly what the questions are.
Definitely a number of things that needed fixing, and great that someone
got around to do it! I don't see why the Chebyshev expansions can't be in
another package if they don't end up in Polynomials.jl.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#179?email_source=notifications&email_token=AADG6TANUJAA2267PR4OI6DQ2EUCNA5CNFSM4I45Z422YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEHR6XLY#issuecomment-568585135>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AADG6TDRHKZHZ64LZE76YSTQ2EUCNANCNFSM4I45Z42Q>
.
--
John Verzani
Department of Mathematics
College of Staten Island, CUNY
verzani@math.csi.cuny.edu
|
|
||
function Base.:+(p1::Polynomial, p2::Polynomial) | ||
p1.var != p2.var && error("Polynomials must have same variable") | ||
n = max(length(p1), length(p2)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In #188 it is seen that this should be n-1, or we could use degree
in place of length
Hi @mileslucas . Sorry, I took a hiatus from this that took longer than I thought it would. But I would like to get your nice work merged. Here are some current thoughts. Hopefully you haven't moved on altogether from this work.
|
Hey, no worries, this has also been on the back-burrner for me. I'm happy to make any changes you see fit to make this work better not only for you as a maintainer but for the community as a whole, too. For the new polynomial basis, I think having the fallback option be convert to polynomial -> operate -> convert back is part of the benefit of abstracting these things. Let's work off your list here and put down concrete steps to get this merged. I fear if we sit too long this will end up dying in PR purgatory. How would you like to organize those changes? |
Great. I have a few things going on: a branch that includes some changes against your PR and the start of a SpecialPolynomials.jl package. I'll push later today. Would love your feedback. |
I have a few repositories to look at: which contains some suggested changes to this main pull request. which contains some implementations of special polynomials. My game plan with this was the following: Version 0.7
✓ hold off on deprecations --> Plots --> Chebyshev --> Docs --> run some benchmarks works with Unitful.jl?X pass, needed changes to + and * are cumbersome Version 0.8
Version 1.0
|
This sounds great. Let me know how/where I should help! Perhaps a good way would be to merge this PR into a diff branch and make PRs off that and then have a final PR when that branch is finished? |
Why don't I make a PR against yours, and you can resolve. Once done, we can merge your branch. That will be 0.7. I'm still unclear about 0.8, but am heavily leaning towards putting the |
Thanks so much @mileslucas !! |
This is a pretty big pull request with a lot of moving parts, I'll do my best to document and update my changes not only within the code but within this PR.
1. Create an
AbstractPolynomial
type and interfaceAllows creation of an abstract interface which requires minor implementations for each type of polynomial.
AbstractPolynomial
typeNote There are some ambiguities that occur when treating
AbstractPolynomial <: Number
, mainly in the arithmetic it is hard to define+(p::AbstractPolynomial, n::Number)
because those types cause an ambiguous function error (related to Should Polynomials subtype Number ? #173, add toml files; v1.0 forward; make subtype of Number close #173 #174)length
,size
, etc.)The existing promotion and conversion rules will stand, in addition the promote type for two
AbstractPolynomial
will bePolynomial
, since every special polynomial can be (somewhat easily) converted to a standard polynomial.zero
,one
, etc.2. The common interface
All polynomials should have the following common methods. This is very similar to the way Distributions.jl handles its abstract types
fromroots(::Type{P}, ....)
create polynomial of typeP
from roots. Defaults toPolynomial
this calls
_fromroots(::Type{P}, ...)
in the concrete implementationfit(::Type{P}, x, y, ...)
fit data using polynomial of typeP
. This relies on_vander(::Type{P}...)
only.roots(p)
return the roots of the polynomial. This relies on_companion(p)
only.coeffs(p)
wrapper forp.coeffs
domain(p), domain(::Type{P})
return the domain of the indeterminate, This relies on_domain
.vander(::Type{P})
just a wrapper for_vander
companion(p)
just a wrapper for_companion
scale_to_domain(p, x)
scale_to_domain(::Type{P}, x)
, return x scaled to the domain of the polynomialvariable(p)
variable(::Type{P})
get the indeterminate of the polynomial.derivative(p, k=1)
return derivate of the polynomialintegral(p, k=0)
return integral of the polynomialtruncate
truncate!
round off and chop leading zeroschop
chop!
chop leading zerosdegree
andorder
norm
andconjugate
This matches most of the previous implementation plus some extra. By defining
fit
as the least-squares solution of the vandermonde matrix_vander
, we only have to implement the latter for each concrete type (same withroots
and_companion
).3. Deprecate Old functionality
Poly
->Polynomial
polyX
-> appropriate new implementation4. New polynomials
ChebyshevT
ChebyshevU
Legendre
Hermite
HermiteHe
Laguerre
Lagrange
5. Documentation
Document everything with doctests and plots :)
6. Tests
Make sure there are no breaking changes via deprecation tests and maintain an equal or greater coverage of functionality