Opened 21 months ago

Last modified 2 months ago

#28922 needs_work enhancement

Function fields: updates to series expansion code

Reported by: gh-BrentBaccala Owned by:
Priority: minor Milestone: sage-9.5
Component: algebraic geometry Keywords: function field
Cc: Merged in:
Authors: Brent Baccala Reviewers:
Report Upstream: N/A Work issues:
Branch: public/28922 (Commits, GitHub, GitLab) Commit: 4189256a741231c4f6cd1305c548fcc05d9fff41
Dependencies: Stopgaps:

Status badges

Description (last modified by gh-BrentBaccala)

This patch changes four things concerning series expansions in the function field code:

  1. The uniformizing variable can be specified

This patch adds an optional local_uniformizer argument to FunctionField's completion() method. It accepts either a function field element or an element of the Symbolic Ring constructed from a root of a function field element. This allows, for example, sqrt(x) to be specified as a uniformizing variable without knowing a specific function field element that is a square root of x.

If the specified element is not a uniformizing variable at the given place, an exception is raised.

  1. If a series expansion is exact, the O(s^n) is dropped. So, for example, the following test case:
K.<x> = FunctionField(QQbar); _.<Y> = K[]
L.<y> = K.extension(Y^2 + Y + x + 1/x)
O = L.maximal_order()
I = O.ideal(y)
pl = I.divisor().support()[0]
m = L.completion(pl, prec=5)
m(x)

now returns I + s instead of I + s + O(s^5).

  1. The precision is now specified as absolute precision, instead of relative. This is a backwards incompatible change made to bring the function field code into alignment with the rest of Sage. So, now, this test:
sage: K.<x> = FunctionField(GF(2)); _.<Y> = K[]
sage: L.<y> = K.extension(Y^2 + Y + x + 1/x)
sage: p = L.places_finite()[0]
sage: m = L.completion(p)
sage: m(x+y, 5)

returns s^-1 + 1 + s^2 + s^4 + O(s^5) instead of s^-1 + 1 + s^2 + O(s^4)

  1. Function field elements can now be raised to fractional powers. If the fractional power does not exist in the function field, a result in the Symbolic Ring is returned. While not, strictly speaking, a change to the series expansion code, this change allows fractional powers like x^(1/3) to be specified as uniformizing variables.

Change History (27)

comment:1 Changed 21 months ago by gh-BrentBaccala

  • Authors set to Brent Baccala
  • Branch set to public/28922
  • Commit set to aa9230c41b708e7ec3df98eafa06ac148597a4c0
  • Description modified (diff)
  • Summary changed from Function fields: allow uniformizing variable to be specified in a completion to Function fields: updates to series expansion code

New commits:

fca168dTrac #28922: allow series completion's uniformizing variable to be specified
2dba013Trac #28922: return exact results for series expansions that are exact
f27c629Trac #28922: modified test cases that now return exact results
dc2b7a7Trac #28922: function field series expansion now uses absolute precision,
aa9230cTrac #28922: simplify a doctest

comment:2 Changed 21 months ago by git

  • Commit changed from aa9230c41b708e7ec3df98eafa06ac148597a4c0 to 734c9b2f542b00f605c152da3edd81cf134ed30c

Branch pushed to git repo; I updated commit sha1. New commits:

012365fTrac #28922: compute fractional powers of function field elements
734c9b2Trac #28922: no longer need to cast into SR to take roots of fraction field elements

comment:3 Changed 21 months ago by gh-BrentBaccala

  • Description modified (diff)

comment:4 Changed 21 months ago by git

  • Commit changed from 734c9b2f542b00f605c152da3edd81cf134ed30c to 59081b1fdfb562fa3dc34766b90a6f83207a9531

Branch pushed to git repo; I updated commit sha1. New commits:

59081b1Merge tag '9.0' into public/28922

comment:5 Changed 21 months ago by gh-BrentBaccala

  • Description modified (diff)
  • Status changed from new to needs_review

comment:6 follow-ups: Changed 21 months ago by klee

  1. The precision is now specified as absolute precision, instead of relative. This is a backwards incompatible change made to bring the function field code into alignment with the rest of Sage.

Why is "absolute precision" more aligned with the rest of Sage? What is the evidence?

comment:7 in reply to: ↑ 6 Changed 21 months ago by gh-BrentBaccala

Replying to klee:

  1. The precision is now specified as absolute precision, instead of relative. This is a backwards incompatible change made to bring the function field code into alignment with the rest of Sage.

Why is "absolute precision" more aligned with the rest of Sage? What is the evidence?

Taylor and Laurent series expansions in the Symbolic Ring are specified using absolute precision.

sage: var('x')
x

sage: sin(x).series(x,4)
1*x + (-1/6)*x^3 + Order(x^4)

sage: (1/(x^2+x)).series(x,4)
1*x^(-1) + (-1) + 1*x + (-1)*x^2 + 1*x^3 + Order(x^4)

I am not aware of any other examples.

Last edited 21 months ago by gh-BrentBaccala (previous) (diff)

comment:8 in reply to: ↑ 6 ; follow-up: Changed 21 months ago by gh-BrentBaccala

Replying to klee:

  1. The precision is now specified as absolute precision, instead of relative. This is a backwards incompatible change made to bring the function field code into alignment with the rest of Sage.

Why is "absolute precision" more aligned with the rest of Sage? What is the evidence?

Have you already written a lot of code that uses relative precision?

comment:9 in reply to: ↑ 8 ; follow-up: Changed 21 months ago by klee

Replying to gh-BrentBaccala:

Replying to klee:

  1. The precision is now specified as absolute precision, instead of relative. This is a backwards incompatible change made to bring the function field code into alignment with the rest of Sage.

Why is "absolute precision" more aligned with the rest of Sage? What is the evidence?

Have you already written a lot of code that uses relative precision?

No. But no change to an existing interface should be made without a compelling reason.

comment:10 in reply to: ↑ 9 Changed 21 months ago by gh-BrentBaccala

Replying to klee:

Replying to gh-BrentBaccala:

Replying to klee:

  1. The precision is now specified as absolute precision, instead of relative. This is a backwards incompatible change made to bring the function field code into alignment with the rest of Sage.

Why is "absolute precision" more aligned with the rest of Sage? What is the evidence?

Have you already written a lot of code that uses relative precision?

No. But no change to an existing interface should be made without a compelling reason.

I agree. I suggest making this change now, since I believe that a uniform interface is a compelling reason.

comment:11 Changed 21 months ago by gh-BrentBaccala

Another reason to use absolute precision is that a common construction is to calculate the principal part of the series expansion (i.e, the negative powers). With absolute precision, it's easier to specify: prec=0 instead of prec=-A.valuation(pl)(f).

comment:12 follow-up: Changed 21 months ago by klee

My comments:

  1. Function field elements can now be raised to fractional powers.

As far as I understand, fractional power, as an operation, is not well defined for elements of an algebraic function field. It may not even exist, and then you return a symbolic ring element. I don't get this. In general, I object to the idea of injecting symbolic ring stuff into exact function field computation.

  1. If a series expansion is exact, the O(s^n) is dropped.

Why slow down series expansion computation to check if it is exact? If you want an exact result for your computation, you can check it and get it. This does not make sense to me.

  1. The uniformizing variable can be specified

Ok. But please use the name local_uniformizeror shortly uniformizer for consistency. This is only acceptable if you do not clutter the series expansion code with the fractional power stuff.

  1. The precision is now specified as absolute precision, instead of relative.

Ok. But this need a deprecation warning as it is an user interface change.

comment:13 in reply to: ↑ 12 ; follow-up: Changed 20 months ago by gh-BrentBaccala

Replying to klee:

My comments:

  1. Function field elements can now be raised to fractional powers.

As far as I understand, fractional power, as an operation, is not well defined for elements of an algebraic function field. It may not even exist, and then you return a symbolic ring element. I don't get this. In general, I object to the idea of injecting symbolic ring stuff into exact function field computation.


OK, I'll drop the symbolic ring stuff, and only return fractional powers if they actually exist, otherwise raise an exception.

I did the symbolic ring stuff so that a uniformizing variable could be specified as something like sqrt(x) even if such an element didn't actually exist.

  1. If a series expansion is exact, the O(s^n) is dropped.

Why slow down series expansion computation to check if it is exact? If you want an exact result for your computation, you can check it and get it. This does not make sense to me.

sage: var('x')
x
sage: x.series(x)
1*x + Order(x^20)

OK, not what I expected, but it's consistent with what you propose.

  1. The uniformizing variable can be specified

Ok. But please use the name local_uniformizeror shortly uniformizer for consistency. This is only acceptable if you do not clutter the series expansion code with the fractional power stuff.


OK, I'll go with local_uniformizer. I'll rip the fractional power stuff out of the series expansion code and require an actual function field element to be specified as the local_uniformizer.

  1. The precision is now specified as absolute precision, instead of relative.

Ok. But this need a deprecation warning as it is an user interface change.


I'm not sure how to do that. The current deprecation warnings are for entire methods that have been dropped. I don't think we have anything to announce that an existing method has changed its interpretation of its arguments, nor can I think of a good way to implement such a warning, since the code could never tell which interpretation was intended.

comment:14 in reply to: ↑ 13 ; follow-up: Changed 20 months ago by klee

Ok. But this need a deprecation warning as it is an user interface change.


I'm not sure how to do that. The current deprecation warnings are for entire methods that have been dropped. I don't think we have anything to announce that an existing method has changed its interpretation of its arguments, nor can I think of a good way to implement such a warning, since the code could never tell which interpretation was intended.

It would suffice to warn the user:

sage.misc.superseded.warning(28922, "Mind that prec now means absolute precision.")

comment:15 in reply to: ↑ 14 Changed 20 months ago by gh-BrentBaccala

  • Description modified (diff)

Replying to klee:

Ok. But this need a deprecation warning as it is an user interface change.


I'm not sure how to do that. The current deprecation warnings are for entire methods that have been dropped. I don't think we have anything to announce that an existing method has changed its interpretation of its arguments, nor can I think of a good way to implement such a warning, since the code could never tell which interpretation was intended.

It would suffice to warn the user:

sage.misc.superseded.warning(28922, "Mind that prec now means absolute precision.")

I don't like that user interface. It seems like the only way to disable the warning is to disable all warnings. Since the Trac number is included in the message, it would be nice to have a feature where warnings associated with given tickets are silenced, but that's another feature entirely.

I'll just drop this change.

comment:16 Changed 20 months ago by git

  • Commit changed from 59081b1fdfb562fa3dc34766b90a6f83207a9531 to 0ab8240ca35d7d87544d99dd5be0cb9bacc3f5aa

Branch pushed to git repo; I updated commit sha1. New commits:

7c9d261Trac #28922: don't check for exact result in series expansion
6df8f55Trac #28922: if a fractional power can't be taken, raise an exception
faeb46dTrac #28922: use 'local_uniformizer' instead of 'uvar' and require
c258884Revert "Trac #28922: function field series expansion now uses absolute precision,"
0ab8240Merge tag '9.1.beta0' into public/28922

comment:17 follow-up: Changed 20 months ago by klee

Is the algorithm for computing the fractional power correct? I don't see how root has the divisor you want.

comment:18 in reply to: ↑ 17 ; follow-up: Changed 20 months ago by gh-BrentBaccala

Replying to klee:

Is the algorithm for computing the fractional power correct? I don't see how root has the divisor you want.

191         numer = right.numerator()
192         denom = right.denominator()
193 
194         if denom == 1:
195             return self._pow_int(right)
196         else:
197             try:
198                 D = self.divisor()
199                 Droot = sum([Integer(m*right)*pl for pl,m in D.dict().items()])
200                 basis = (-Droot).basis_function_space()
201                 root = basis[0]
202                 coeff = self.parent().constant_base_field()(self**numer)/(root**denom))**(1/denom)
203                 return coeff*root
204             except (TypeError, IndexError):
205                 pass
206             raise ValueError("not a %s power"%Integer(denom).ordinal_str())

The algorithm's logic runs like this:

  1. Valuations are multiplicative homomorphisms, i.e, μ(fg) = μ(f) + μ(g)
  2. This implies μ(fn) = nμ(f)
  3. So if the divisor of f is ∑mP, the divisor of fn is ∑nmP
  4. All of the nm products have to be integers for this to be a well-formed divisor
  5. This yields line 199, with TypeError raised if any of nm's aren't integers
  6. Droot has total degree zero, so basis will have either zero or one elements
  7. If it has zero elements, line 201 will raise IndexError
  8. If we make it to line 202, we've found an element with the correct divisor

Is there a flaw in any of this?

comment:19 in reply to: ↑ 18 ; follow-up: Changed 20 months ago by klee

Replying to gh-BrentBaccala:

The algorithm's logic runs like this:

  1. Valuations are multiplicative homomorphisms, i.e, μ(fg) = μ(f) + μ(g)
  2. This implies μ(fn) = nμ(f)
  3. So if the divisor of f is ∑mP, the divisor of fn is ∑nmP
  4. All of the nm products have to be integers for this to be a well-formed divisor
  5. This yields line 199, with TypeError raised if any of nm's aren't integers
  6. Droot has total degree zero, so basis will have either zero or one elements
  7. If it has zero elements, line 201 will raise IndexError
  8. If we make it to line 202, we've found an element with the correct divisor

I see. Thanks.

It seems you are assuming the constant field is full, that is, the base constant field is the algebraic closure of itself. Right? Then perhaps you can develop the algorithm further such that it works without that assumption. Moreover this would be a prerequisite for is_square to work correctly.

comment:20 in reply to: ↑ 19 ; follow-up: Changed 20 months ago by gh-BrentBaccala

Replying to klee:

I see. Thanks.

It seems you are assuming the constant field is full, that is, the base constant field is the algebraic closure of itself. Right? Then perhaps you can develop the algorithm further such that it works without that assumption. Moreover this would be a prerequisite for is_square to work correctly.

That's very likely. I work almost exclusively with algebraically closed constant fields. Where is the problem, exactly? I'm guessing it has to do with the behavior of the divisors?

comment:21 in reply to: ↑ 20 ; follow-up: Changed 20 months ago by klee

Replying to gh-BrentBaccala:

Replying to klee:

I see. Thanks.

It seems you are assuming the constant field is full, that is, the base constant field is the algebraic closure of itself. Right? Then perhaps you can develop the algorithm further such that it works without that assumption. Moreover this would be a prerequisite for is_square to work correctly.

That's very likely. I work almost exclusively with algebraically closed constant fields. Where is the problem, exactly? I'm guessing it has to do with the behavior of the divisors?

self/root^n is in the full constant field, which is the Riemann-Roch space of zero divisor.

Last edited 20 months ago by klee (previous) (diff)

comment:22 in reply to: ↑ 21 Changed 20 months ago by gh-BrentBaccala

  • Status changed from needs_review to needs_work

Replying to klee:

Replying to gh-BrentBaccala:

Replying to klee:

I see. Thanks.

It seems you are assuming the constant field is full, that is, the base constant field is the algebraic closure of itself. Right? Then perhaps you can develop the algorithm further such that it works without that assumption. Moreover this would be a prerequisite for is_square to work correctly.

That's very likely. I work almost exclusively with algebraically closed constant fields. Where is the problem, exactly? I'm guessing it has to do with the behavior of the divisors?

self/root^n is in the full constant field, which is the Riemann-Roch space of zero divisor.

OK, I see.

Thank you.

I spent quite a while convincing myself that the homomorphism logic in steps 1-5 was correct, but I never considered for a minute that the zero divisor might have dimension greater than one.

comment:23 Changed 17 months ago by mkoeppe

  • Milestone changed from sage-9.1 to sage-9.2

Batch modifying tickets that will likely not be ready for 9.1, based on a review of the ticket title, branch/review status, and last modification date.

comment:24 Changed 14 months ago by git

  • Commit changed from 0ab8240ca35d7d87544d99dd5be0cb9bacc3f5aa to 4189256a741231c4f6cd1305c548fcc05d9fff41

Branch pushed to git repo; I updated commit sha1. New commits:

8240552Merge tag '9.2.beta0' into public/28922
6fd8451Trac #28922: silence pyflakes warnings
4189256an attempt to implement __pow__ for function field elements... but

comment:25 Changed 13 months ago by mkoeppe

  • Milestone changed from sage-9.2 to sage-9.3

comment:26 Changed 7 months ago by mkoeppe

  • Milestone changed from sage-9.3 to sage-9.4

Setting new milestone based on a cursory review of ticket status, priority, and last modification date.

comment:27 Changed 2 months ago by mkoeppe

  • Milestone changed from sage-9.4 to sage-9.5

Setting a new milestone for this ticket based on a cursory review.

Note: See TracTickets for help on using tickets.