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

Add DomainError positive char univariate polynomial rings #199

Merged
merged 2 commits into from
Aug 27, 2024

Conversation

GiacomoPope
Copy link
Contributor

@GiacomoPope GiacomoPope commented Aug 27, 2024

Following the discussion in #62

add DomainError for real_roots and complex_roots for positive characteristic univariate polys
Comment on lines 257 to 261
def real_roots(self):
raise AttributeError("Real roots are not supported for this polynomial")

def complex_roots(self):
raise AttributeError("Complex roots are not supported for this polynomial")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should be something like NotImplementedError at least rather than AttributeError. The meaning of AttributeError is that an object does not have an attribute. It should not be used for anything else.

@oscarbenjamin
Copy link
Collaborator

This looks good.

We don't necessarily need to do it here but to complete these we should add an implementation of real_roots for arb_poly, fmpz_poly and fmpq_poly.

For arb_poly it is:

def real_roots(self):
    return self.roots()

For fmpz_poly we just need a square-free factorisation (all poly have this now after gh-189). Then convert to arb_poly to compute the roots:

def real_roots(self):
    _, fac = self.factor_squarefree()
    roots = []
    for f, m in fac:
        roots.extend([(r, m) for r, m in arb_poly(f).roots()])
    # Sort the roots?
    return roots

For fmpq_poly the real roots are the real roots of the numerator:

def real_roots(self):
    return self.numer().real_roots()

Oh, wait arb_poly does not have roots:

In [4]: arb_poly([1, 0, 1]).roots()
...
NotImplementedError: Polynomial has no factor method, roots cannot be determined

I guess we need to add real_roots to acb_poly using acb_poly_validate_real_roots and then arb_poly can have:

def roots(self):
    return acb_poly(self).real_roots()

Oh, and there is an interface inconsistency:

In [12]: acb_poly([1, 0, -1]).roots()
Out[12]: [-1.00000000000000, 1.00000000000000]

In [13]: fmpz_poly([1, 0, -1]).roots()
Out[13]: [(1, 1), (-1, 1)]

I suppose that acb_poly and arb_poly could have a different interface for now...

@oscarbenjamin
Copy link
Collaborator

Or maybe for fmpz_poly.real_roots it should just filter the roots from fmpz_poly.complex_roots(). There seems to be
arb_fmpz_poly_complex_roots but no separate method for real roots.

@oscarbenjamin
Copy link
Collaborator

I assume that there is some advantage in using arb_fmpz_poly_complex_roots rather than acb_poly_validate_real_roots for the case where we have exact fmpz coefficients. Not sure, but isolating all complex roots is a vastly more expensive operation than isolating only real roots...

@oscarbenjamin
Copy link
Collaborator

Okay, let's just merge this for now and consider proper real_roots support later.

@oscarbenjamin oscarbenjamin merged commit 9a0327f into flintlib:master Aug 27, 2024
38 checks passed
@GiacomoPope GiacomoPope deleted the real_complex_root branch August 27, 2024 14:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants