Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/schemes/generic/scheme.py
8820 views
1
"""
2
Schemes
3
4
AUTHORS:
5
6
- William Stein, David Kohel, Kiran Kedlaya (2008): added zeta_series
7
8
- Volker Braun (2011-08-11): documenting, improving, refactoring.
9
"""
10
11
12
#*****************************************************************************
13
# Copyright (C) 2011 Volker Braun <[email protected]>
14
# Copyright (C) 2008 Kiran Kedlaya <[email protected]>
15
# Copyright (C) 2005 David Kohel <[email protected]>
16
# Copyright (C) 2005 William Stein
17
#
18
# Distributed under the terms of the GNU General Public License (GPL)
19
# as published by the Free Software Foundation; either version 2 of
20
# the License, or (at your option) any later version.
21
# http://www.gnu.org/licenses/
22
#*****************************************************************************
23
24
25
from sage.structure.parent import Parent
26
from sage.misc.all import cached_method
27
from sage.rings.all import (IntegerRing,
28
ZZ, GF, PowerSeriesRing,
29
Rationals)
30
31
from sage.rings.commutative_ring import is_CommutativeRing
32
from sage.rings.morphism import is_RingHomomorphism
33
34
def is_Scheme(x):
35
"""
36
Test whether ``x`` is a scheme.
37
38
INPUT:
39
40
- ``x`` -- anything.
41
42
OUTPUT:
43
44
Boolean. Whether ``x`` derives from :class:`Scheme`.
45
46
EXAMPLES::
47
48
sage: from sage.schemes.generic.scheme import is_Scheme
49
sage: is_Scheme(5)
50
False
51
sage: X = Spec(QQ)
52
sage: is_Scheme(X)
53
True
54
"""
55
return isinstance(x, Scheme)
56
57
58
59
class Scheme(Parent):
60
"""
61
The base class for all schemes.
62
63
INPUT:
64
65
- ``X`` -- a scheme, scheme morphism, commutative ring,
66
commutative ring morphism, or ``None`` (optional). Determines
67
the base scheme. If a commutative ring is passed, the spectrum
68
of the ring will be used as base.
69
70
- ``category`` -- the category (optional). Will be automatically
71
construted by default.
72
73
EXAMPLES::
74
75
sage: from sage.schemes.generic.scheme import Scheme
76
sage: Scheme(ZZ)
77
<class 'sage.schemes.generic.scheme.Scheme_with_category'>
78
79
A scheme is in the category of all schemes over its base::
80
81
sage: ProjectiveSpace(4, QQ).category()
82
Category of schemes over Rational Field
83
84
There is a special and unique `Spec(\ZZ)` that is the default base
85
scheme::
86
87
sage: Spec(ZZ).base_scheme() is Spec(QQ).base_scheme()
88
True
89
"""
90
91
def __init__(self, X=None, category=None):
92
"""
93
Construct a scheme.
94
95
TESTS::
96
97
sage: R.<x, y> = QQ[]
98
sage: I = (x^2 - y^2)*R
99
sage: RmodI = R.quotient(I)
100
sage: X = Spec(RmodI)
101
sage: TestSuite(X).run(skip = ["_test_an_element", "_test_elements",
102
... "_test_some_elements", "_test_category"]) # See #7946
103
"""
104
from sage.schemes.generic.spec import is_Spec
105
from sage.schemes.generic.morphism import is_SchemeMorphism
106
107
if X is None:
108
try:
109
from sage.schemes.generic.spec import SpecZ
110
self._base_scheme = SpecZ
111
except ImportError: # we are currently constructing SpecZ
112
self._base_ring = ZZ
113
elif is_Scheme(X):
114
self._base_scheme = X
115
elif is_SchemeMorphism(X):
116
self._base_morphism = X
117
elif is_CommutativeRing(X):
118
self._base_ring = X
119
elif is_RingHomomorphism(X):
120
self._base_ring = X.codomain()
121
else:
122
raise ValueError('The base must be define by a scheme, '
123
'scheme morphism, or commutative ring.')
124
125
from sage.categories.schemes import Schemes
126
if not X:
127
default_category = Schemes()
128
else:
129
default_category = Schemes(self.base_scheme())
130
if category is None:
131
category = default_category
132
else:
133
assert category.is_subcategory(default_category), \
134
"%s is not a subcategory of %s"%(category, default_category)
135
136
Parent.__init__(self, self.base_ring(), category = category)
137
138
def __cmp__(left, right):
139
"""
140
Compare two schemes.
141
142
INPUT:
143
144
- ``right`` -- anything. To compare against the scheme
145
``left``.
146
147
OUTPUT:
148
149
``+1``, ``0``, or ``-1``.
150
151
EXAMPLES::
152
153
sage: X = Spec(QQ); Y = Spec(QQ)
154
sage: X == Y
155
True
156
sage: X is Y
157
False
158
"""
159
if not is_Scheme(right):
160
return -1
161
return left._cmp_(right)
162
163
def union(self, X):
164
"""
165
Return the disjoint union of the schemes ``self`` and ``X``.
166
167
EXAMPLES::
168
169
sage: S = Spec(QQ)
170
sage: X = AffineSpace(1, QQ)
171
sage: S.union(X)
172
Traceback (most recent call last):
173
...
174
NotImplementedError
175
"""
176
raise NotImplementedError
177
178
__add__ = union
179
180
def _morphism(self, *args, **kwds):
181
"""
182
Construct a morphism determined by action on points of ``self``.
183
184
EXAMPLES::
185
186
sage: X = Spec(QQ)
187
sage: X._morphism()
188
Traceback (most recent call last):
189
...
190
NotImplementedError
191
192
TESTS:
193
194
This shows that issue at trac ticket 7389 is solved::
195
196
sage: S = Spec(ZZ)
197
sage: f = S.identity_morphism()
198
sage: from sage.schemes.generic.glue import GluedScheme
199
sage: T = GluedScheme(f,f)
200
sage: S.hom([1],T)
201
Traceback (most recent call last):
202
...
203
NotImplementedError
204
"""
205
raise NotImplementedError
206
207
def base_extend(self, Y):
208
"""
209
Extend the base of the scheme.
210
211
Derived clases must override this method.
212
213
EXAMPLES::
214
215
sage: from sage.schemes.generic.scheme import Scheme
216
sage: X = Scheme(ZZ)
217
sage: X.base_scheme()
218
Spectrum of Integer Ring
219
sage: X.base_extend(QQ)
220
Traceback (most recent call last):
221
...
222
NotImplementedError
223
"""
224
raise NotImplementedError
225
226
def __call__(self, *args):
227
"""
228
Call syntax for schemes.
229
230
INPUT/OUTPUT:
231
232
The arguments must be one of the following:
233
234
- a ring or a scheme `S`. Output will be the set `X(S)` of
235
`S`-valued points on `X`.
236
237
- If `S` is a list or tuple or just the coordinates, return a
238
point in `X(T)`, where `T` is the base scheme of self.
239
240
EXAMPLES::
241
242
sage: A = AffineSpace(2, QQ)
243
244
We create some point sets::
245
246
sage: A(QQ)
247
Set of rational points of Affine Space of dimension 2 over Rational Field
248
sage: A(RR)
249
Set of rational points of Affine Space of dimension 2 over Real Field
250
with 53 bits of precision
251
252
Space of dimension 2 over Rational Field::
253
254
sage: R.<x> = PolynomialRing(QQ)
255
sage: A(NumberField(x^2+1, 'a'))
256
Set of rational points of Affine Space of dimension 2 over Number Field
257
in a with defining polynomial x^2 + 1
258
sage: A(GF(7))
259
Traceback (most recent call last):
260
...
261
ValueError: There must be a natural map S --> R, but
262
S = Rational Field and R = Finite Field of size 7
263
264
We create some points::
265
266
sage: A(QQ)([1,0])
267
(1, 0)
268
269
We create the same point by giving the coordinates of the point
270
directly::
271
272
sage: A( 1,0 )
273
(1, 0)
274
"""
275
if len(args) == 0:
276
raise TypeError('You need to specify at least one argument.')
277
278
S = args[0]
279
if is_CommutativeRing(S):
280
return self.point_homset(S)
281
if is_Scheme(S):
282
return S.Hom(self)
283
from sage.schemes.generic.morphism import SchemeMorphism_point
284
if isinstance(S, (list, tuple)):
285
args = S
286
elif isinstance(S, SchemeMorphism_point):
287
if S.codomain() == self:
288
return S
289
else:
290
# TODO: fix circular import resulting from non-multiple inheritance
291
from sage.schemes.elliptic_curves.ell_point import EllipticCurvePoint_field
292
if isinstance(S, EllipticCurvePoint_field):
293
if S.codomain() == self:
294
return S
295
else:
296
return self.point(S)
297
return self.point(args)
298
299
@cached_method
300
def point_homset(self, S=None):
301
"""
302
Return the set of S-valued points of this scheme.
303
304
INPUT:
305
306
- ``S`` -- a commutative ring.
307
308
OUTPUT:
309
310
The set of morphisms `Spec(S)\to X`.
311
312
EXAMPLES::
313
314
sage: P = ProjectiveSpace(ZZ, 3)
315
sage: P.point_homset(ZZ)
316
Set of rational points of Projective Space of dimension 3 over Integer Ring
317
sage: P.point_homset(QQ)
318
Set of rational points of Projective Space of dimension 3 over Rational Field
319
sage: P.point_homset(GF(11))
320
Set of rational points of Projective Space of dimension 3 over
321
Finite Field of size 11
322
323
TESTS::
324
325
sage: P = ProjectiveSpace(QQ,3)
326
sage: P.point_homset(GF(11))
327
Traceback (most recent call last):
328
...
329
ValueError: There must be a natural map S --> R, but
330
S = Rational Field and R = Finite Field of size 11
331
"""
332
if S is None:
333
S = self.base_ring()
334
from sage.schemes.generic.spec import Spec
335
SpecS = Spec(S, self.base_ring())
336
from sage.schemes.generic.homset import SchemeHomset
337
return SchemeHomset(SpecS, self)
338
339
def point(self, v, check=True):
340
"""
341
Create a point.
342
343
INPUT:
344
345
- ``v`` -- anything that defines a point.
346
347
- ``check`` -- boolean (optional, default=``True``). Whether
348
to check the defining data for consistency.
349
350
OUTPUT:
351
352
A point of the scheme.
353
354
EXAMPLES::
355
356
sage: A2 = AffineSpace(QQ,2)
357
sage: A2.point([4,5])
358
(4, 5)
359
360
sage: R.<t> = PolynomialRing(QQ)
361
sage: E = EllipticCurve([t + 1, t, t, 0, 0])
362
sage: E.point([0, 0])
363
(0 : 0 : 1)
364
"""
365
# todo: update elliptic curve stuff to take point_homset as argument
366
from sage.schemes.elliptic_curves.ell_generic import is_EllipticCurve
367
if is_EllipticCurve(self):
368
try:
369
return self._point(self.point_homset(), v, check=check)
370
except AttributeError: # legacy code without point_homset
371
return self._point(self, v, check=check)
372
373
return self.point_homset() (v, check=check)
374
375
def _point(self):
376
"""
377
Return the Hom-set from some affine scheme to ``self``.
378
379
OUTPUT:
380
381
A scheme Hom-set, see :mod:`~sage.schemes.generic.homset`.
382
383
EXAMPLES::
384
385
sage: X = Spec(QQ)
386
sage: X._point()
387
Traceback (most recent call last):
388
...
389
NotImplementedError
390
"""
391
raise NotImplementedError
392
393
def _point_homset(self, *args, **kwds):
394
"""
395
Return the Hom-set from ``self`` to another scheme.
396
397
EXAMPLES::
398
399
sage: from sage.schemes.generic.scheme import Scheme
400
sage: X = Scheme(QQ)
401
sage: X._point_homset()
402
Traceback (most recent call last):
403
...
404
NotImplementedError
405
"""
406
raise NotImplementedError
407
408
def __div__(self, Y):
409
"""
410
Return the base extension of self to Y.
411
412
See :meth:`base_extend` for details.
413
414
EXAMPLES::
415
416
sage: A = AffineSpace(3, ZZ)
417
sage: A
418
Affine Space of dimension 3 over Integer Ring
419
sage: A/QQ
420
Affine Space of dimension 3 over Rational Field
421
sage: A/GF(7)
422
Affine Space of dimension 3 over Finite Field of size 7
423
"""
424
return self.base_extend(Y)
425
426
def base_ring(self):
427
"""
428
Return the base ring of the scheme self.
429
430
OUTPUT:
431
432
A commutative ring.
433
434
EXAMPLES::
435
436
sage: A = AffineSpace(4, QQ)
437
sage: A.base_ring()
438
Rational Field
439
440
sage: X = Spec(QQ)
441
sage: X.base_ring()
442
Integer Ring
443
"""
444
try:
445
return self._base_ring
446
except AttributeError:
447
if hasattr(self, '_base_morphism'):
448
self._base_ring = self._base_morphism.codomain().coordinate_ring()
449
elif hasattr(self, '_base_scheme'):
450
self._base_ring = self._base_scheme.coordinate_ring()
451
else:
452
self._base_ring = ZZ
453
return self._base_ring
454
455
def base_scheme(self):
456
"""
457
Return the base scheme.
458
459
OUTPUT:
460
461
A scheme.
462
463
EXAMPLES::
464
465
sage: A = AffineSpace(4, QQ)
466
sage: A.base_scheme()
467
Spectrum of Rational Field
468
469
sage: X = Spec(QQ)
470
sage: X.base_scheme()
471
Spectrum of Integer Ring
472
"""
473
try:
474
return self._base_scheme
475
except AttributeError:
476
if hasattr(self, '_base_morphism'):
477
self._base_scheme = self._base_morphism.codomain()
478
elif hasattr(self, '_base_ring'):
479
from sage.schemes.generic.spec import Spec
480
self._base_scheme = Spec(self._base_ring)
481
else:
482
from sage.schemes.generic.spec import SpecZ
483
self._base_scheme = SpecZ
484
return self._base_scheme
485
486
def base_morphism(self):
487
"""
488
Return the structure morphism from ``self`` to its base
489
scheme.
490
491
OUTPUT:
492
493
A scheme morphism.
494
495
EXAMPLES::
496
497
sage: A = AffineSpace(4, QQ)
498
sage: A.base_morphism()
499
Scheme morphism:
500
From: Affine Space of dimension 4 over Rational Field
501
To: Spectrum of Rational Field
502
Defn: Structure map
503
504
sage: X = Spec(QQ)
505
sage: X.base_morphism()
506
Scheme morphism:
507
From: Spectrum of Rational Field
508
To: Spectrum of Integer Ring
509
Defn: Structure map
510
"""
511
try:
512
return self._base_morphism
513
except AttributeError:
514
from sage.categories.schemes import Schemes
515
from sage.schemes.generic.spec import Spec, SpecZ
516
SCH = Schemes()
517
if hasattr(self, '_base_scheme'):
518
self._base_morphism = self.Hom(self._base_scheme, category=SCH).natural_map()
519
elif hasattr(self, '_base_ring'):
520
self._base_morphism = self.Hom(Spec(self._base_ring), category=SCH).natural_map()
521
else:
522
self._base_morphism = self.Hom(SpecZ, category=SCH).natural_map()
523
return self._base_morphism
524
525
structure_morphism = base_morphism
526
527
def coordinate_ring(self):
528
"""
529
Return the coordinate ring.
530
531
OUTPUT:
532
533
The global coordinate ring of this scheme, if
534
defined. Otherwise raise a ``ValueError``.
535
536
EXAMPLES::
537
538
sage: R.<x, y> = QQ[]
539
sage: I = (x^2 - y^2)*R
540
sage: X = Spec(R.quotient(I))
541
sage: X.coordinate_ring()
542
Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2 - y^2)
543
"""
544
try:
545
return self._coordinate_ring
546
except AttributeError:
547
raise ValueError, "This scheme has no associated coordinated ring (defined)."
548
549
def dimension_absolute(self):
550
"""
551
Return the absolute dimension of this scheme.
552
553
OUTPUT:
554
555
Integer.
556
557
EXAMPLES::
558
559
sage: R.<x, y> = QQ[]
560
sage: I = (x^2 - y^2)*R
561
sage: X = Spec(R.quotient(I))
562
sage: X.dimension_absolute()
563
Traceback (most recent call last):
564
...
565
NotImplementedError
566
sage: X.dimension()
567
Traceback (most recent call last):
568
...
569
NotImplementedError
570
"""
571
raise NotImplementedError # override in derived class
572
573
dimension = dimension_absolute
574
575
def dimension_relative(self):
576
"""
577
Return the relative dimension of this scheme over its base.
578
579
OUTPUT:
580
581
Integer.
582
583
EXAMPLES::
584
585
sage: R.<x, y> = QQ[]
586
sage: I = (x^2 - y^2)*R
587
sage: X = Spec(R.quotient(I))
588
sage: X.dimension_relative()
589
Traceback (most recent call last):
590
...
591
NotImplementedError
592
"""
593
raise NotImplementedError # override in derived class
594
595
def identity_morphism(self):
596
"""
597
Return the identity morphism.
598
599
OUTPUT:
600
601
The identity morphism of the scheme ``self``.
602
603
EXAMPLES::
604
605
sage: X = Spec(QQ)
606
sage: X.identity_morphism()
607
Scheme endomorphism of Spectrum of Rational Field
608
Defn: Identity map
609
"""
610
from sage.schemes.generic.morphism import SchemeMorphism_id
611
return SchemeMorphism_id(self)
612
613
def hom(self, x, Y=None, check=True):
614
"""
615
Return the scheme morphism from ``self`` to ``Y`` defined by ``x``.
616
617
INPUT:
618
619
- ``x`` -- anything hat determines a scheme morphism. If ``x``
620
is a scheme, try to determine a natural map to ``x``.
621
622
- ``Y`` -- the codomain scheme (optional). If ``Y`` is not
623
given, try to determine ``Y`` from context.
624
625
- ``check`` -- boolean (optional, default=``True``). Whether
626
to check the defining data for consistency.
627
628
OUTPUT:
629
630
The scheme morphism from ``self`` to ``Y`` defined by ``x``.
631
632
EXAMPLES::
633
634
sage: P = ProjectiveSpace(ZZ, 3)
635
sage: P.hom(Spec(ZZ))
636
Scheme morphism:
637
From: Projective Space of dimension 3 over Integer Ring
638
To: Spectrum of Integer Ring
639
Defn: Structure map
640
"""
641
if Y is None:
642
if is_Scheme(x):
643
return self.Hom(x).natural_map()
644
else:
645
raise TypeError, "unable to determine codomain"
646
return self.Hom(Y)(x, check)
647
648
def _Hom_(self, Y, category=None, check=True):
649
"""
650
Return the set of scheme morphisms from ``self`` to ``Y``.
651
652
INPUT:
653
654
- ``Y`` -- a scheme. The codomain of the Hom-set.
655
656
- ``category`` -- a category (optional). The category of the
657
Hom-set.
658
659
- ``check`` -- boolean (optional, default=``True``). Whether
660
to check the defining data for consistency.
661
662
OUTPUT:
663
664
The set of morphisms from ``self`` to ``Y``.
665
666
EXAMPLES::
667
668
sage: P = ProjectiveSpace(ZZ, 3)
669
sage: S = Spec(ZZ)
670
sage: S._Hom_(P)
671
Set of rational points of Projective Space of dimension 3 over Integer Ring
672
673
TESTS::
674
675
sage: S._Hom_(P).__class__
676
<class 'sage.schemes.projective.projective_homset.SchemeHomset_points_projective_ring_with_category'>
677
678
sage: E = EllipticCurve('37a1')
679
sage: Hom(E, E).__class__
680
<class 'sage.schemes.generic.homset.SchemeHomset_generic_with_category'>
681
682
sage: Hom(Spec(ZZ), Spec(ZZ)).__class__
683
<class 'sage.schemes.affine.affine_homset.SchemeHomset_points_spec_with_category'>
684
"""
685
from sage.schemes.generic.homset import SchemeHomset
686
return SchemeHomset(self, Y, category=category, check=check)
687
688
point_set = point_homset
689
690
def count_points(self, n):
691
r"""
692
Count points over finite fields.
693
694
INPUT:
695
696
- ``n`` -- integer.
697
698
OUTPUT:
699
700
An integer. The number of points over `\GF{q}, \ldots,
701
\GF{q^n}` on a scheme over a finite field `\GF{q}`.
702
703
.. note::
704
705
This is currently only implemented for schemes over prime
706
order finite fields.
707
708
EXAMPLES::
709
710
sage: P.<x> = PolynomialRing(GF(3))
711
sage: C = HyperellipticCurve(x^3+x^2+1)
712
sage: C.count_points(4)
713
[6, 12, 18, 96]
714
sage: C.base_extend(GF(9,'a')).count_points(2)
715
Traceback (most recent call last):
716
...
717
NotImplementedError: Point counting only implemented for schemes over prime fields
718
"""
719
F = self.base_ring()
720
if not F.is_finite():
721
raise TypeError, "Point counting only defined for schemes over finite fields"
722
q = F.cardinality()
723
if not q.is_prime():
724
raise NotImplementedError, "Point counting only implemented for schemes over prime fields"
725
a = []
726
for i in range(1, n+1):
727
F1 = GF(q**i, name='z')
728
S1 = self.base_extend(F1)
729
a.append(len(S1.rational_points()))
730
return(a)
731
732
def zeta_series(self, n, t):
733
"""
734
Return the zeta series.
735
736
Compute a power series approximation to the zeta function of a
737
scheme over a finite field.
738
739
INPUT:
740
741
- ``n`` -- the number of terms of the power series to
742
compute
743
744
- ``t`` -- the variable which the series should be
745
returned
746
747
748
OUTPUT:
749
750
A power series approximating the zeta function of self
751
752
EXAMPLES::
753
754
sage: P.<x> = PolynomialRing(GF(3))
755
sage: C = HyperellipticCurve(x^3+x^2+1)
756
sage: R.<t> = PowerSeriesRing(Integers())
757
sage: C.zeta_series(4,t)
758
1 + 6*t + 24*t^2 + 78*t^3 + 240*t^4 + O(t^5)
759
sage: (1+2*t+3*t^2)/(1-t)/(1-3*t) + O(t^5)
760
1 + 6*t + 24*t^2 + 78*t^3 + 240*t^4 + O(t^5)
761
762
Note that this function depends on count_points, which is only
763
defined for prime order fields::
764
765
sage: C.base_extend(GF(9,'a')).zeta_series(4,t)
766
Traceback (most recent call last):
767
...
768
NotImplementedError: Point counting only implemented for schemes over prime fields
769
"""
770
771
F = self.base_ring()
772
if not F.is_finite():
773
raise TypeError('zeta functions only defined for schemes over finite fields')
774
try:
775
a = self.count_points(n)
776
except AttributeError:
777
raise NotImplementedError('count_points() required but not implemented')
778
R = PowerSeriesRing(Rationals(), 'u')
779
u = R.gen()
780
temp = sum(a[i-1]*(u.O(n+1))**i/i for i in range(1,n+1))
781
temp2 = temp.exp()
782
return(temp2(t).O(n+1))
783
784
def is_AffineScheme(x):
785
"""
786
Return True if `x` is an affine scheme.
787
788
EXAMPLES::
789
790
sage: from sage.schemes.generic.scheme import is_AffineScheme
791
sage: is_AffineScheme(5)
792
False
793
sage: E = Spec(QQ)
794
sage: is_AffineScheme(E)
795
True
796
"""
797
return isinstance(x, AffineScheme)
798
799
class AffineScheme(Scheme):
800
"""
801
An abstract affine scheme.
802
"""
803
def hom(self, x, Y=None):
804
r"""
805
Return the scheme morphism from ``self`` to ``Y`` defined by ``x``.
806
807
INPUT:
808
809
- ``x`` -- anything hat determines a scheme morphism. If ``x``
810
is a scheme, try to determine a natural map to ``x``.
811
812
- ``Y`` -- the codomain scheme (optional). If ``Y`` is not
813
given, try to determine ``Y`` from context.
814
815
- ``check`` -- boolean (optional, default=``True``). Whether
816
to check the defining data for consistency.
817
818
OUTPUT:
819
820
The scheme morphism from ``self`` to ``Y`` defined by ``x``.
821
822
EXAMPLES:
823
824
We construct the inclusion from `\mathrm{Spec}(\QQ)` into
825
`\mathrm{Spec}(\ZZ)` induced by the inclusion from `\ZZ` into
826
`\QQ`::
827
828
sage: X = Spec(QQ)
829
sage: X.hom(ZZ.hom(QQ))
830
Affine Scheme morphism:
831
From: Spectrum of Rational Field
832
To: Spectrum of Integer Ring
833
Defn: Ring Coercion morphism:
834
From: Integer Ring
835
To: Rational Field
836
837
TESTS:
838
839
We can construct a morphism to an affine curve (trac #7956)::
840
841
sage: S.<p,q> = QQ[]
842
sage: A1.<r> = AffineSpace(QQ,1)
843
sage: A1_emb = Curve(p-2)
844
sage: A1.hom([2,r],A1_emb)
845
Scheme morphism:
846
From: Affine Space of dimension 1 over Rational Field
847
To: Affine Curve over Rational Field defined by p - 2
848
Defn: Defined on coordinates by sending (r) to
849
(2, r)
850
851
"""
852
if is_Scheme(x):
853
return self.Hom(x).natural_map()
854
if Y is None:
855
if is_RingHomomorphism(x):
856
import spec
857
Y = spec.Spec(x.domain())
858
return Scheme.hom(self, x, Y)
859
860
861