Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/geometry/newton_polygon.py
8815 views
1
"""
2
This module implements finite Newton polygons and
3
infinite Newton polygons having a finite number of
4
slopes (and hence a last infinite slope).
5
"""
6
7
#############################################################################
8
# Copyright (C) 2013 Xavier Caruso <[email protected]>
9
#
10
# Distributed under the terms of the GNU General Public License (GPL)
11
#
12
# http://www.gnu.org/licenses/
13
#############################################################################
14
15
from sage.structure.unique_representation import UniqueRepresentation
16
from sage.structure.parent import Parent
17
from sage.structure.element import Element
18
from sage.misc.cachefunc import cached_method
19
20
from sage.rings.infinity import Infinity
21
from sage.geometry.polyhedron.constructor import Polyhedron
22
from sage.geometry.polyhedron.base import is_Polyhedron
23
24
25
class NewtonPolygon_element(Element):
26
"""
27
Class for infinite Newton polygons with last slope.
28
"""
29
def __init__(self, polyhedron, parent):
30
"""
31
Initialize a Newton polygon.
32
33
INPUT:
34
35
- polyhedron -- a polyhedron defining the Newton polygon
36
37
TESTS:
38
39
sage: from sage.geometry.newton_polygon import NewtonPolygon
40
sage: NewtonPolygon([ (0,0), (1,1), (3,5) ])
41
Finite Newton polygon with 3 vertices: (0, 0), (1, 1), (3, 5)
42
43
sage: NewtonPolygon([ (0,0), (1,1), (2,8), (3,5) ], last_slope=3)
44
Infinite Newton polygon with 3 vertices: (0, 0), (1, 1), (3, 5) ending by an infinite line of slope 3
45
46
::
47
48
sage: TestSuite(NewtonPolygon).run()
49
"""
50
Element.__init__(self, parent)
51
self._polyhedron = polyhedron
52
self._vertices = None
53
54
def _repr_(self):
55
"""
56
Return a string representation of this Newton polygon.
57
58
EXAMPLES:
59
60
sage: from sage.geometry.newton_polygon import NewtonPolygon
61
sage: NP = NewtonPolygon([ (0,0), (1,1), (2,5) ]); NP
62
Finite Newton polygon with 3 vertices: (0, 0), (1, 1), (2, 5)
63
64
sage: NP._repr_()
65
'Finite Newton polygon with 3 vertices: (0, 0), (1, 1), (2, 5)'
66
"""
67
vertices = self.vertices()
68
length = len(vertices)
69
if self.last_slope() is Infinity:
70
if length == 0:
71
return "Empty Newton polygon"
72
elif length == 1:
73
return "Finite Newton polygon with 1 vertex: %s" % str(vertices[0])
74
else:
75
return "Finite Newton polygon with %s vertices: %s" % (length, str(vertices)[1:-1])
76
else:
77
if length == 1:
78
return "Newton Polygon consisting of a unique infinite line of slope %s starting at %s" % (self.last_slope(), str(vertices[0]))
79
else:
80
return "Infinite Newton polygon with %s vertices: %s ending by an infinite line of slope %s" % (length, str(vertices)[1:-1], self.last_slope())
81
82
def vertices(self, copy=True):
83
"""
84
Returns the list of vertices of this Newton polygon
85
86
INPUT:
87
88
- ``copy`` -- a boolean (default: ``True``)
89
90
OUTPUT:
91
92
The list of vertices of this Newton polygon (or a copy of it
93
if ``copy`` is set to True)
94
95
EXAMPLES:
96
97
sage: from sage.geometry.newton_polygon import NewtonPolygon
98
sage: NP = NewtonPolygon([ (0,0), (1,1), (2,5) ]); NP
99
Finite Newton polygon with 3 vertices: (0, 0), (1, 1), (2, 5)
100
101
sage: v = NP.vertices(); v
102
[(0, 0), (1, 1), (2, 5)]
103
104
TESTS:
105
106
sage: del v[0]
107
sage: v
108
[(1, 1), (2, 5)]
109
sage: NP.vertices()
110
[(0, 0), (1, 1), (2, 5)]
111
"""
112
if self._vertices is None:
113
self._vertices = [ tuple(v) for v in self._polyhedron.vertices() ]
114
self._vertices.sort()
115
if copy:
116
return list(self._vertices)
117
else:
118
return self._vertices
119
120
@cached_method
121
def last_slope(self):
122
"""
123
Returns the last (infinite) slope of this Newton polygon
124
if it is infinite and ``+Infinity`` otherwise.
125
126
EXAMPLES:
127
128
sage: from sage.geometry.newton_polygon import NewtonPolygon
129
sage: NP1 = NewtonPolygon([ (0,0), (1,1), (2,8), (3,5) ], last_slope=3)
130
sage: NP1.last_slope()
131
3
132
133
sage: NP2 = NewtonPolygon([ (0,0), (1,1), (2,5) ])
134
sage: NP2.last_slope()
135
+Infinity
136
137
We check that the last slope of a sum (resp. a produit) is the
138
minimum of the last slopes of the summands (resp. the factors)::
139
140
sage: (NP1 + NP2).last_slope()
141
3
142
sage: (NP1 * NP2).last_slope()
143
3
144
"""
145
rays = self._polyhedron.rays()
146
for r in rays:
147
if r[0] > 0:
148
return r[1]/r[0]
149
return Infinity
150
151
def slopes(self, repetition=True):
152
"""
153
Returns the slopes of this Newton polygon
154
155
INPUT:
156
157
- ``repetition`` -- a boolean (default: ``True``)
158
159
OUTPUT:
160
161
The consecutive slopes (not including the last slope
162
if the polygon is infinity) of this Newton polygon.
163
164
If ``repetition`` is True, each slope is repeated a number of
165
times equal to its length. Otherwise, it appears only one time.
166
167
EXAMPLES:
168
169
sage: from sage.geometry.newton_polygon import NewtonPolygon
170
sage: NP = NewtonPolygon([ (0,0), (1,1), (3,6) ]); NP
171
Finite Newton polygon with 3 vertices: (0, 0), (1, 1), (3, 6)
172
173
sage: NP.slopes()
174
[1, 5/2, 5/2]
175
176
sage: NP.slopes(repetition=False)
177
[1, 5/2]
178
"""
179
slopes = [ ]
180
vertices = self.vertices(copy=False)
181
for i in range(1,len(vertices)):
182
dx = vertices[i][0] - vertices[i-1][0]
183
dy = vertices[i][1] - vertices[i-1][1]
184
slope = dy/dx
185
if repetition:
186
slopes.extend(dx * [slope])
187
else:
188
slopes.append(slope)
189
return slopes
190
191
def _add_(self, other):
192
"""
193
Returns the convex hull of ``self`` and ``other``
194
195
INPUT:
196
197
- ``other`` -- a Newton polygon
198
199
OUTPUT:
200
201
The Newton polygon, which is the convex hull of this Newton polygon and ``other``
202
203
EXAMPLES:
204
205
sage: from sage.geometry.newton_polygon import NewtonPolygon
206
sage: NP1 = NewtonPolygon([ (0,0), (1,1), (2,6) ]); NP1
207
Finite Newton polygon with 3 vertices: (0, 0), (1, 1), (2, 6)
208
sage: NP2 = NewtonPolygon([ (0,0), (1,3/2) ], last_slope=2); NP2
209
Infinite Newton polygon with 2 vertices: (0, 0), (1, 3/2) ending by an infinite line of slope 2
210
211
sage: NP1 + NP2
212
Infinite Newton polygon with 2 vertices: (0, 0), (1, 1) ending by an infinite line of slope 2
213
"""
214
polyhedron = self._polyhedron.convex_hull(other._polyhedron)
215
return self.parent()(polyhedron)
216
217
def _mul_(self, other):
218
"""
219
Returns the Minkowski sum of ``self`` and ``other``
220
221
INPUT:
222
223
- ``other`` -- a Newton polygon
224
225
OUTPUT:
226
227
The Newton polygon, which is the Minkowski sum of this Newton polygon and ``other``.
228
229
NOTE::
230
231
If ``self`` and ``other`` are respective Newton polygons of some polynomials
232
`f` and `g` the self*other is the Newton polygon of the product `fg`
233
234
EXAMPLES:
235
236
sage: from sage.geometry.newton_polygon import NewtonPolygon
237
sage: NP1 = NewtonPolygon([ (0,0), (1,1), (2,6) ]); NP1
238
Finite Newton polygon with 3 vertices: (0, 0), (1, 1), (2, 6)
239
sage: NP2 = NewtonPolygon([ (0,0), (1,3/2) ], last_slope=2); NP2
240
Infinite Newton polygon with 2 vertices: (0, 0), (1, 3/2) ending by an infinite line of slope 2
241
242
sage: NP = NP1 * NP2; NP
243
Infinite Newton polygon with 3 vertices: (0, 0), (1, 1), (2, 5/2) ending by an infinite line of slope 2
244
245
The slopes of ``NP`` is the union of thos of ``NP1`` and those of ``NP2``
246
which are less than the last slope::
247
248
sage: NP1.slopes()
249
[1, 5]
250
sage: NP2.slopes()
251
[3/2]
252
sage: NP.slopes()
253
[1, 3/2]
254
"""
255
polyhedron = self._polyhedron.Minkowski_sum(other._polyhedron)
256
return self.parent()(polyhedron)
257
258
def __pow__(self, exp, ignored=None):
259
"""
260
Returns ``self`` dilated by ``exp``
261
262
INPUT:
263
264
- ``exp`` -- a positive integer
265
266
OUTPUT:
267
268
This Newton polygon scaled by a factor ``exp``.
269
270
NOTE::
271
272
If ``self`` is the Newton polygon of a polynomial `f`, then
273
``self^exp`` is the Newton polygon of `f^{exp}`.
274
275
EXAMPLES:
276
277
sage: from sage.geometry.newton_polygon import NewtonPolygon
278
sage: NP = NewtonPolygon([ (0,0), (1,1), (2,6) ]); NP
279
Finite Newton polygon with 3 vertices: (0, 0), (1, 1), (2, 6)
280
281
sage: NP^10
282
Finite Newton polygon with 3 vertices: (0, 0), (10, 10), (20, 60)
283
"""
284
polyhedron = self._polyhedron.dilation(exp)
285
return self.parent()(polyhedron)
286
287
def __lshift__(self, i):
288
"""
289
Returns ``self`` shifted by `(0,i)`
290
291
INPUT:
292
293
- ``i`` -- a rational number
294
295
OUTPUT:
296
297
This Newton polygon shifted by the vector `(0,i)`
298
299
EXAMPLES:
300
301
sage: from sage.geometry.newton_polygon import NewtonPolygon
302
sage: NP = NewtonPolygon([ (0,0), (1,1), (2,6) ]); NP
303
Finite Newton polygon with 3 vertices: (0, 0), (1, 1), (2, 6)
304
305
sage: NP << 2
306
Finite Newton polygon with 3 vertices: (0, 2), (1, 3), (2, 8)
307
"""
308
polyhedron = self._polyhedron.translation((0,i))
309
return self.parent()(polyhedron)
310
311
def __rshift__(self, i):
312
"""
313
Returns ``self`` shifted by `(0,-i)`
314
315
INPUT:
316
317
- ``i`` -- a rational number
318
319
OUTPUT:
320
321
This Newton polygon shifted by the vector `(0,-i)`
322
323
EXAMPLES:
324
325
sage: from sage.geometry.newton_polygon import NewtonPolygon
326
sage: NP = NewtonPolygon([ (0,0), (1,1), (2,6) ]); NP
327
Finite Newton polygon with 3 vertices: (0, 0), (1, 1), (2, 6)
328
329
sage: NP >> 2
330
Finite Newton polygon with 3 vertices: (0, -2), (1, -1), (2, 4)
331
"""
332
polyhedron = self._polyhedron.translation((0,-i))
333
return self.parent()(polyhedron)
334
335
def __call__(self, x):
336
"""
337
Returns `self(x)`
338
339
INPUT:
340
341
- ``x`` -- a real number
342
343
OUTPUT:
344
345
The value of this Newton polygon at abscissa `x`
346
347
EXAMPLES:
348
349
sage: from sage.geometry.newton_polygon import NewtonPolygon
350
sage: NP = NewtonPolygon([ (0,0), (1,1), (3,6) ]); NP
351
Finite Newton polygon with 3 vertices: (0, 0), (1, 1), (3, 6)
352
353
sage: [ NP(i) for i in range(4) ]
354
[0, 1, 7/2, 6]
355
"""
356
# complexity: O(log(n))
357
from sage.functions.other import floor
358
vertices = self.vertices()
359
lastslope = self.last_slope()
360
if len(vertices) == 0 or x < vertices[0][0]:
361
return Infinity
362
if x == vertices[0][0]:
363
return vertices[0][1]
364
if x == vertices[-1][0]:
365
return vertices[-1][1]
366
if x > vertices[-1][0]:
367
return vertices[-1][1] + lastslope * (x - vertices[-1][0])
368
a = 0; b = len(vertices)
369
while b - a > 1:
370
c = floor((a+b)/2)
371
if vertices[c][0] < x:
372
a = c
373
else:
374
b = c
375
(xg,yg) = vertices[a]
376
(xd,yd) = vertices[b]
377
return ((x-xg)*yd + (xd-x)*yg) / (xd-xg)
378
379
def __eq__(self, other):
380
"""
381
TESTS:
382
383
sage: from sage.geometry.newton_polygon import NewtonPolygon
384
sage: NP1 = NewtonPolygon([ (0,0), (1,1), (3,6) ])
385
sage: NP2 = NewtonPolygon([ (0,0), (1,1), (2,6), (3,6) ])
386
sage: NP1 == NP2
387
True
388
"""
389
if not isinstance(other, NewtonPolygon_element):
390
return False
391
return self._polyhedron == other._polyhedron
392
393
def __ne__(self, other):
394
"""
395
TESTS:
396
397
sage: from sage.geometry.newton_polygon import NewtonPolygon
398
sage: NP1 = NewtonPolygon([ (0,0), (1,1), (3,6) ])
399
sage: NP2 = NewtonPolygon([ (0,0), (1,1), (2,6), (3,6) ])
400
sage: NP1 != NP2
401
False
402
"""
403
return not (self == other)
404
405
def __le__(self, other):
406
"""
407
INPUT:
408
409
- ``other`` -- an other Newton polygon
410
411
OUTPUT:
412
413
Return True is this Newton polygon lies below ``other``
414
415
EXAMPLES:
416
417
sage: from sage.geometry.newton_polygon import NewtonPolygon
418
sage: NP1 = NewtonPolygon([ (0,0), (1,1), (2,6) ])
419
sage: NP2 = NewtonPolygon([ (0,0), (1,3/2) ], last_slope=2)
420
sage: NP1 <= NP2
421
False
422
423
sage: NP1 + NP2 <= NP1
424
True
425
sage: NP1 + NP2 <= NP2
426
True
427
"""
428
if not isinstance(other, NewtonPolygon_element):
429
raise TypeError("Impossible to compare a Newton Polygon with something else")
430
if self.last_slope() > other.last_slope():
431
return False
432
for v in other.vertices():
433
if not v in self._polyhedron:
434
return False
435
return True
436
437
def __lt__(self, other):
438
"""
439
TESTS:
440
441
sage: from sage.geometry.newton_polygon import NewtonPolygon
442
sage: NP1 = NewtonPolygon([ (0,0), (1,1), (2,6) ])
443
sage: NP2 = NewtonPolygon([ (0,0), (1,3/2) ], last_slope=2)
444
sage: NP1 < NP1
445
False
446
sage: NP1 < NP2
447
False
448
449
sage: NP1 + NP2 < NP2
450
True
451
"""
452
return self <= other and self != other
453
454
def __ge__(self, other):
455
"""
456
TESTS:
457
458
sage: from sage.geometry.newton_polygon import NewtonPolygon
459
sage: NP1 = NewtonPolygon([ (0,0), (1,1), (2,6) ])
460
sage: NP2 = NewtonPolygon([ (0,0), (1,3/2) ], last_slope=2)
461
sage: NP1 >= NP2
462
False
463
464
sage: NP1 >= NP1 + NP2
465
True
466
sage: NP2 >= NP1 + NP2
467
True
468
"""
469
return other <= self
470
471
def __gt__(self, other):
472
"""
473
TESTS:
474
475
sage: from sage.geometry.newton_polygon import NewtonPolygon
476
sage: NP1 = NewtonPolygon([ (0,0), (1,1), (2,6) ])
477
sage: NP2 = NewtonPolygon([ (0,0), (1,3/2) ], last_slope=2)
478
sage: NP1 > NP1
479
False
480
sage: NP1 > NP2
481
False
482
483
sage: NP1 > NP1 + NP2
484
True
485
"""
486
return other <= self and self != other
487
488
def plot(self, **kwargs):
489
"""
490
Plot this Newton polygon.
491
492
.. NOTE::
493
494
All usual rendering options (color, thickness, etc.) are available.
495
496
EXAMPLES:
497
498
sage: from sage.geometry.newton_polygon import NewtonPolygon
499
sage: NP = NewtonPolygon([ (0,0), (1,1), (2,6) ])
500
sage: polygon = NP.plot()
501
"""
502
vertices = self.vertices()
503
if len(vertices) == 0:
504
from sage.plot.graphics import Graphics
505
return Graphics()
506
else:
507
from sage.plot.line import line
508
(xstart,ystart) = vertices[0]
509
(xend,yend) = vertices[-1]
510
if self.last_slope() is Infinity:
511
return line([(xstart, ystart+1), (xstart,ystart+0.5)], linestyle="--", **kwargs) \
512
+ line([(xstart, ystart+0.5)] + vertices + [(xend, yend+0.5)], **kwargs) \
513
+ line([(xend, yend+0.5), (xend, yend+1)], linestyle="--", **kwargs)
514
else:
515
return line([(xstart, ystart+1), (xstart,ystart+0.5)], linestyle="--", **kwargs) \
516
+ line([(xstart, ystart+0.5)] + vertices + [(xend+0.5, yend + 0.5*self.last_slope())], **kwargs) \
517
+ line([(xend+0.5, yend + 0.5*self.last_slope()), (xend+1, yend+self.last_slope())], linestyle="--", **kwargs)
518
519
def reverse(self, degree=None):
520
"""
521
Returns the symmetric of ``self``
522
523
INPUT:
524
525
- ``degree`` -- an integer (default: the top right abscissa of
526
this Newton polygon)
527
528
OUTPUT:
529
530
The image this Newton polygon under the symmetry
531
'(x,y) \mapsto (degree-x, y)`
532
533
EXAMPLES:
534
535
sage: from sage.geometry.newton_polygon import NewtonPolygon
536
sage: NP = NewtonPolygon([ (0,0), (1,1), (2,5) ])
537
sage: NP2 = NP.reverse(); NP2
538
Finite Newton polygon with 3 vertices: (0, 5), (1, 1), (2, 0)
539
540
We check that the slopes of the symmetric Newton polygon are
541
the opposites of the slopes of the original Newton polygon::
542
543
sage: NP.slopes()
544
[1, 4]
545
sage: NP2.slopes()
546
[-4, -1]
547
"""
548
if self.last_slope() is not Infinity:
549
raise ValueError("Can only reverse *finite* Newton polygons")
550
if degree is None:
551
degree = self.vertices()[-1][0]
552
vertices = [ (degree-x,y) for (x,y) in self.vertices() ]
553
vertices.reverse()
554
parent = self.parent()
555
polyhedron = Polyhedron(base_ring=parent.base_ring(), vertices=vertices, rays=[(0,1)])
556
return parent(polyhedron)
557
558
559
560
561
class ParentNewtonPolygon(Parent, UniqueRepresentation):
562
"""
563
Construct a Newton polygon.
564
565
INPUT:
566
567
- ``arg`` -- a list/tuple/iterable of vertices or of
568
slopes. Currently, slopes must be rational numbers.
569
570
- ``sort_slopes`` -- boolean (default: ``True``). Specifying
571
whether slopes must be first sorted
572
573
- ``last_slope`` -- rational or infinity (default:
574
``Infinity``). The last slope of the Newton polygon
575
576
OUTPUT:
577
578
The corresponding Newton polygon.
579
580
.. note::
581
582
By convention, a Newton polygon always contains the point
583
at infinity `(0, \infty)`. These polygons are attached to
584
polynomials or series over discrete valuation rings (e.g. padics).
585
586
EXAMPLES:
587
588
We specify here a Newton polygon by its vertices::
589
590
sage: from sage.geometry.newton_polygon import NewtonPolygon
591
sage: NewtonPolygon([ (0,0), (1,1), (3,5) ])
592
Finite Newton polygon with 3 vertices: (0, 0), (1, 1), (3, 5)
593
594
We note that the convex hull of the vertices is automatically
595
computed::
596
597
sage: NewtonPolygon([ (0,0), (1,1), (2,8), (3,5) ])
598
Finite Newton polygon with 3 vertices: (0, 0), (1, 1), (3, 5)
599
600
Note that the value ``+Infinity`` is allowed as the second coordinate
601
of a vertex::
602
603
sage: NewtonPolygon([ (0,0), (1,Infinity), (2,8), (3,5) ])
604
Finite Newton polygon with 2 vertices: (0, 0), (3, 5)
605
606
If last_slope is set, the returned Newton polygon is infinite
607
and ends with an infinite line having the specified slope::
608
609
sage: NewtonPolygon([ (0,0), (1,1), (2,8), (3,5) ], last_slope=3)
610
Infinite Newton polygon with 3 vertices: (0, 0), (1, 1), (3, 5) ending by an infinite line of slope 3
611
612
Specifying a last slope may discard some vertices::
613
614
sage: NewtonPolygon([ (0,0), (1,1), (2,8), (3,5) ], last_slope=3/2)
615
Infinite Newton polygon with 2 vertices: (0, 0), (1, 1) ending by an infinite line of slope 3/2
616
617
Next, we define a Newton polygon by its slopes::
618
619
sage: NP = NewtonPolygon([0, 1/2, 1/2, 2/3, 2/3, 2/3, 1, 1])
620
sage: NP
621
Finite Newton polygon with 5 vertices: (0, 0), (1, 0), (3, 1), (6, 3), (8, 5)
622
sage: NP.slopes()
623
[0, 1/2, 1/2, 2/3, 2/3, 2/3, 1, 1]
624
625
By default, slopes are automatically sorted::
626
627
sage: NP2 = NewtonPolygon([0, 1, 1/2, 2/3, 1/2, 2/3, 1, 2/3])
628
sage: NP2
629
Finite Newton polygon with 5 vertices: (0, 0), (1, 0), (3, 1), (6, 3), (8, 5)
630
sage: NP == NP2
631
True
632
633
except if the contrary is explicitely mentionned::
634
635
sage: NewtonPolygon([0, 1, 1/2, 2/3, 1/2, 2/3, 1, 2/3], sort_slopes=False)
636
Finite Newton polygon with 4 vertices: (0, 0), (1, 0), (6, 10/3), (8, 5)
637
638
Slopes greater that or equal last_slope (if specified) are discarded::
639
640
sage: NP = NewtonPolygon([0, 1/2, 1/2, 2/3, 2/3, 2/3, 1, 1], last_slope=2/3)
641
sage: NP
642
Infinite Newton polygon with 3 vertices: (0, 0), (1, 0), (3, 1) ending by an infinite line of slope 2/3
643
sage: NP.slopes()
644
[0, 1/2, 1/2]
645
646
::
647
648
Be careful, do not confuse Newton polygons provided by this class
649
with Newton polytopes. Compare::
650
651
sage: NP = NewtonPolygon([ (0,0), (1,45), (3,6) ]); NP
652
Finite Newton polygon with 2 vertices: (0, 0), (3, 6)
653
654
sage: x, y = polygen(QQ,'x, y')
655
sage: p = 1 + x*y**45 + x**3*y**6
656
sage: p.newton_polytope()
657
A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices
658
sage: p.newton_polytope().vertices()
659
(A vertex at (0, 0), A vertex at (1, 45), A vertex at (3, 6))
660
"""
661
662
Element = NewtonPolygon_element
663
664
def __init__(self):
665
"""
666
Parent class for all Newton polygons.
667
668
sage: from sage.geometry.newton_polygon import ParentNewtonPolygon
669
sage: ParentNewtonPolygon()
670
Parent for Newton polygons
671
672
TESTS:
673
674
This class is a singleton.
675
676
sage: ParentNewtonPolygon() is ParentNewtonPolygon()
677
True
678
679
::
680
681
sage: TestSuite(ParentNewtonPolygon()).run()
682
"""
683
from sage.categories.semirings import Semirings
684
from sage.rings.rational_field import QQ
685
Parent.__init__(self, category=Semirings(), base=QQ)
686
687
def _repr_(self):
688
"""
689
Returns the string representation of this parent,
690
which is ``Parent for Newton polygons``
691
692
TESTS:
693
694
sage: from sage.geometry.newton_polygon import NewtonPolygon
695
sage: NewtonPolygon
696
Parent for Newton polygons
697
698
sage: NewtonPolygon._repr_()
699
'Parent for Newton polygons'
700
"""
701
return "Parent for Newton polygons"
702
703
def _an_element_(self):
704
"""
705
Returns a Newton polygon (which is the empty one)
706
707
TESTS:
708
709
sage: from sage.geometry.newton_polygon import NewtonPolygon
710
sage: NewtonPolygon._an_element_()
711
Empty Newton polygon
712
"""
713
return self(Polyhedron(base_ring=self.base_ring(), ambient_dim=2))
714
715
def _element_constructor_(self, arg, sort_slopes=True, last_slope=Infinity):
716
"""
717
INPUT:
718
719
- ``arg`` -- an argument describing the Newton polygon
720
721
- ``sort_slopes`` -- boolean (default: ``True``). Specifying
722
whether slopes must be first sorted
723
724
- ``last_slope`` -- rational or infinity (default:
725
``Infinity``). The last slope of the Newton polygon
726
727
The first argument ``arg`` can be either:
728
729
- a polyhedron in `\QQ^2`
730
731
- the element ``0`` (corresponding to the empty Newton polygon)
732
733
- the element ``1`` (corresponding to the Newton polygon of the
734
constant polynomial equal to 1)
735
736
- a list/tuple/iterable of vertices
737
738
- a list/tuple/iterable of slopes
739
740
OUTPUT:
741
742
The corresponding Newton polygon.
743
744
For more informations, see :class:`ParentNewtonPolygon`.
745
746
TESTS:
747
748
sage: from sage.geometry.newton_polygon import NewtonPolygon
749
sage: NewtonPolygon(0)
750
Empty Newton polygon
751
sage: NewtonPolygon(1)
752
Finite Newton polygon with 1 vertex: (0, 0)
753
"""
754
if is_Polyhedron(arg):
755
return self.element_class(arg, parent=self)
756
if arg == 0:
757
polyhedron = Polyhedron(base_ring=self.base_ring(), ambient_dim=2)
758
return self.element_class(polyhedron, parent=self)
759
if arg == 1:
760
polyhedron = Polyhedron(base_ring=self.base_ring(),
761
vertices=[(0,0)], rays=[(0,1)])
762
return self.element_class(polyhedron, parent=self)
763
if not isinstance(arg, list):
764
try:
765
arg = list(arg)
766
except TypeError:
767
raise TypeError("argument must be a list of coordinates or a list of (rational) slopes")
768
if len(arg) > 0 and arg[0] in self.base_ring():
769
if sort_slopes: arg.sort()
770
x = y = 0
771
vertices = [(x, y)]
772
for slope in arg:
773
if not slope in self.base_ring():
774
raise TypeError("argument must be a list of coordinates or a list of (rational) slopes")
775
x += 1
776
y += slope
777
vertices.append((x,y))
778
else:
779
vertices = [(x, y) for (x, y) in arg if y is not Infinity]
780
if len(vertices) == 0:
781
polyhedron = Polyhedron(base_ring=self.base_ring(), ambient_dim=2)
782
else:
783
rays = [(0, 1)]
784
if last_slope is not Infinity:
785
rays.append((1, last_slope))
786
polyhedron = Polyhedron(base_ring=self.base_ring(), vertices=vertices, rays=rays)
787
return self.element_class(polyhedron, parent=self)
788
789
790
NewtonPolygon = ParentNewtonPolygon()
791
792