Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

363

364

365

366

367

368

369

370

371

372

373

374

375

376

377

378

379

380

381

382

383

384

385

386

387

388

389

390

391

392

393

394

395

396

397

398

399

400

401

402

403

404

405

406

407

408

409

410

411

412

413

414

415

416

417

418

419

420

421

422

423

424

425

426

427

428

429

430

431

432

433

434

435

436

437

438

439

440

441

442

443

444

445

446

447

448

449

450

451

452

453

454

455

456

457

458

459

460

461

462

463

464

465

466

467

468

469

470

471

472

473

474

475

476

477

478

479

480

481

482

483

484

485

486

487

488

489

490

491

492

493

494

495

496

497

498

499

500

501

502

503

504

505

506

507

508

509

510

511

512

513

514

515

516

517

518

519

520

521

522

523

524

525

526

527

528

529

530

531

532

533

534

535

536

537

538

539

540

541

542

543

544

545

546

547

548

549

550

551

552

553

554

555

556

557

558

559

560

561

562

563

564

565

566

567

568

569

570

571

572

573

574

575

576

577

578

579

580

581

582

583

584

585

586

587

588

589

590

591

592

593

594

595

596

597

598

599

600

601

602

603

604

605

606

607

608

609

610

611

612

613

614

615

616

617

618

619

620

621

622

623

624

625

626

627

628

629

630

631

632

633

634

635

636

637

638

639

640

641

642

643

644

645

646

647

648

649

650

651

652

653

654

655

656

657

658

659

660

661

662

663

664

665

666

667

668

669

670

671

672

673

674

675

676

677

678

679

680

681

682

683

684

685

686

687

688

689

690

691

692

693

694

695

696

697

698

699

700

701

702

703

704

705

706

707

708

709

710

711

712

713

714

715

716

717

718

719

720

721

722

723

724

725

726

727

728

729

730

731

732

733

734

735

736

737

738

739

740

741

742

743

744

745

746

747

748

749

750

751

752

753

754

755

756

757

758

759

760

761

762

763

764

765

766

767

768

769

770

771

772

773

774

775

776

777

778

779

780

781

782

783

784

785

786

787

788

789

790

791

792

793

794

795

796

797

798

799

800

801

802

803

804

805

806

807

808

809

810

811

812

813

814

815

816

817

818

819

820

821

822

823

824

825

826

827

828

829

830

831

832

833

834

835

836

837

838

839

840

841

842

843

844

845

846

847

848

849

850

851

852

853

854

855

856

857

858

859

860

861

862

863

864

865

866

867

868

869

870

871

872

873

874

875

876

877

878

879

880

881

882

883

884

885

886

887

888

889

890

891

892

893

894

895

896

897

898

899

900

901

902

903

904

905

906

907

908

909

910

911

912

913

914

915

916

917

918

919

920

921

922

923

924

925

926

927

928

929

930

931

932

933

934

935

936

937

938

939

940

941

942

943

944

945

946

947

948

949

950

951

952

953

954

955

956

957

958

959

960

961

962

963

964

965

966

967

968

969

970

971

972

973

974

975

976

977

978

979

980

981

982

983

984

985

986

987

988

989

990

991

992

993

994

995

996

997

998

999

1000

1001

1002

1003

1004

1005

1006

1007

1008

1009

1010

1011

1012

1013

1014

1015

1016

1017

1018

1019

1020

1021

1022

1023

1024

1025

1026

1027

1028

1029

1030

1031

1032

1033

1034

1035

1036

1037

1038

1039

1040

1041

1042

1043

1044

1045

1046

1047

1048

1049

1050

1051

1052

1053

1054

1055

1056

1057

1058

1059

1060

1061

1062

1063

1064

1065

1066

1067

1068

1069

1070

1071

1072

1073

1074

1075

1076

1077

1078

1079

1080

1081

1082

1083

1084

1085

1086

1087

1088

1089

1090

1091

1092

1093

1094

1095

1096

1097

1098

1099

1100

1101

1102

1103

1104

1105

1106

1107

1108

1109

1110

1111

1112

1113

1114

1115

1116

1117

1118

1119

1120

1121

1122

1123

1124

1125

1126

1127

1128

1129

1130

1131

1132

1133

1134

1135

1136

1137

1138

1139

1140

1141

1142

1143

1144

1145

1146

1147

1148

1149

1150

1151

1152

1153

1154

1155

1156

1157

1158

1159

1160

1161

1162

1163

1164

1165

1166

1167

1168

1169

1170

1171

1172

1173

1174

1175

1176

1177

1178

1179

1180

1181

1182

1183

1184

1185

1186

1187

1188

1189

1190

1191

1192

1193

1194

1195

1196

1197

1198

1199

1200

1201

1202

1203

1204

1205

1206

1207

1208

1209

1210

1211

1212

1213

1214

1215

1216

1217

1218

1219

1220

1221

1222

1223

1224

1225

1226

1227

1228

1229

1230

1231

1232

1233

1234

1235

1236

1237

1238

1239

1240

1241

1242

1243

1244

1245

1246

1247

1248

1249

""" 

This file gives a class from which all the `p`-adic templates inherit. 

  

This file is included in the various precision template files (such as 

sage/rings/padics/CR_template.pxi). While this choice means that routines here 

do have access to the inlined functions defined in the linkage files, the 

downside is that there will be multiple ``pAdicTemplateElement`` 

classes, one for each `p`-adic template. 

  

AUTHORS: 

  

- David Roe -- initial version (2012-3-1) 

""" 

  

#***************************************************************************** 

# Copyright (C) 2007-2013 David Roe <roed.math@gmail.com> 

# William Stein <wstein@gmail.com> 

# 

# Distributed under the terms of the GNU General Public License (GPL) 

# as published by the Free Software Foundation; either version 2 of 

# the License, or (at your option) any later version. 

# 

# http://www.gnu.org/licenses/ 

#***************************************************************************** 

  

from cpython.int cimport * 

  

from sage.libs.gmp.all cimport * 

import sage.rings.finite_rings.integer_mod 

from cypari2.types cimport * 

from cypari2.gen cimport Gen as pari_gen 

from sage.libs.pari.convert_gmp cimport INT_to_mpz 

from sage.rings.padics.common_conversion cimport get_ordp, get_preccap 

from sage.rings.integer cimport Integer 

from sage.rings.infinity import infinity 

from sage.rings.rational import Rational 

from sage.rings.padics.precision_error import PrecisionError 

from sage.rings.padics.misc import trim_zeros 

from sage.structure.element import canonical_coercion 

from sage.misc.superseded import deprecation 

import itertools 

  

cdef long maxordp = (1L << (sizeof(long) * 8 - 2)) - 1 

cdef long minusmaxordp = -maxordp 

  

cdef inline int check_ordp(long ordp) except -1: 

""" 

Checks for overflow after addition or subtraction of valuations. 

  

There is another variant, :meth:`check_ordp_mpz`, for ``mpz_t`` input. 

  

If overflow is detected, raises a OverflowError. 

""" 

if ordp >= maxordp or ordp <= minusmaxordp: 

raise OverflowError("valuation overflow") 

  

cdef class pAdicTemplateElement(pAdicGenericElement): 

""" 

A class for common functionality among the `p`-adic template classes. 

  

INPUT: 

  

- ``parent`` -- a local ring or field 

  

- ``x`` -- data defining this element. Various types are supported, 

including ints, Integers, Rationals, PARI p-adics, integers mod `p^k` 

and other Sage p-adics. 

  

- ``absprec`` -- a cap on the absolute precision of this element 

  

- ``relprec`` -- a cap on the relative precision of this element 

  

EXAMPLES:: 

  

sage: Zp(17)(17^3, 8, 4) 

17^3 + O(17^7) 

""" 

def __init__(self, parent, x, absprec=infinity, relprec=infinity): 

""" 

Initialization. 

  

.. NOTE:: 

  

This initialization function is not called for Integers 

and Rationals since a conversion morphism has been 

implemented. It is, however, used for python ints and longs. 

  

EXAMPLES:: 

  

sage: a = Zp(5)(1/2,3); a 

3 + 2*5 + 2*5^2 + O(5^3) 

sage: type(a) 

<type 'sage.rings.padics.padic_capped_relative_element.pAdicCappedRelativeElement'> 

sage: TestSuite(a).run() 

  

TESTS:: 

  

sage: QQq.<zz> = Qq(25,4) 

sage: FFp = Zp(5,5).residue_field() 

sage: QQq(FFp.zero()) 

O(5) 

sage: QQq(FFp.one()) 

1 + O(5) 

sage: QQq(IntegerModRing(25)(15)) 

3*5 + O(5^2) 

sage: QQq(IntegerModRing(9)(0)) 

Traceback (most recent call last): 

... 

TypeError: p does not divide modulus 9 

  

""" 

self.prime_pow = <PowComputer_?>parent.prime_pow 

pAdicGenericElement.__init__(self, parent) 

cdef long val, xprec 

cdef GEN pari_tmp 

if isinstance(x, (int, long)): 

x = Integer(x) 

elif isinstance(x, pari_gen): 

pari_tmp = (<pari_gen>x).g 

if typ(pari_tmp) == t_INT: 

x = PY_NEW(Integer) 

INT_to_mpz((<Integer>x).value, pari_tmp) 

elif typ(pari_tmp) == t_FRAC: 

x = Rational(x) 

elif isinstance(x, pAdicGenericElement): 

if not ((<pAdicGenericElement>x)._is_base_elt(self.prime_pow.prime) or x.parent() is self.parent()): 

raise NotImplementedError("conversion between padic extensions not implemented") 

elif sage.rings.finite_rings.integer_mod.is_IntegerMod(x): 

if not Integer(self.prime_pow.prime).divides(x.parent().order()): 

raise TypeError("p does not divide modulus %s"%x.parent().order()) 

elif sage.rings.finite_rings.element_base.is_FiniteFieldElement(x): 

k = self.parent().residue_field() 

if not k.has_coerce_map_from(x.parent()): 

raise NotImplementedError("conversion from finite fields which do not embed into the residue field not implemented.") 

  

x = k(x) 

if not k.is_prime_field(): 

x = [k.prime_subfield()(c) for c in x.polynomial().list()] 

x = x + [k.prime_subfield().zero()] * (k.degree() - len(x)) 

elif isinstance(x, (Integer, Rational, list, tuple)): 

pass 

elif sage.rings.polynomial.polynomial_element.is_Polynomial(x) and x.variable_name() == self.parent().variable_name(): 

x = x.list() 

else: 

x = Rational(x) 

val = get_ordp(x, self.prime_pow) 

if val < 0 and self.prime_pow.in_field == 0: 

raise ValueError("negative valuation") 

xprec = get_preccap(x, self.prime_pow) 

self._set(x, val, xprec, absprec, relprec) 

  

cdef int _set(self, x, long val, long xprec, absprec, relprec) except -1: 

""" 

Sets this element from given data computed in :meth:`__init__`. 

  

INPUT: 

  

- ``x`` -- an int, Integer, Rational, PARI p-adic, integer mod `p^k` or Sage p-adic 

  

- ``val`` -- a long, the valuation of ``x`` 

  

- ``xprec`` -- a long, the cap on the absolute precision imposed by ``x`` 

  

- ``absprec`` -- an integer or infinity, a bound on the absolute precision 

  

- ``relprec`` -- an integer or infinity, a bound on the relative precision 

  

""" 

raise NotImplementedError 

  

cdef pAdicTemplateElement _new_with_value(self, celement value, long absprec): 

""" 

Creates a new element with a given value and absolute precision. 

  

Used by code that doesn't know the precision type. 

""" 

raise NotImplementedError 

  

cdef int _get_unit(self, celement value) except -1: 

""" 

Sets ``value`` to the unit of this p-adic element. 

""" 

raise NotImplementedError 

  

def __lshift__(pAdicTemplateElement self, shift): 

""" 

Multiplies ``self`` by ``pi^shift``. 

  

If ``shift`` is negative and this element does not lie in a field, 

digits may be truncated. See ``__rshift__`` for details. 

  

EXAMPLES: 

  

We create some `p`-adic rings:: 

  

sage: R = Zp(5, 20, 'capped-abs'); a = R(1000); a 

3*5^3 + 5^4 + O(5^20) 

sage: S = Zp(5); b = S(1000); b 

3*5^3 + 5^4 + O(5^23) 

  

Shifting to the right is the same as dividing by a power of 

the uniformizer `p` of the `p`-adic ring.:: 

  

sage: a >> 1 

3*5^2 + 5^3 + O(5^19) 

sage: b >> 1 

3*5^2 + 5^3 + O(5^22) 

  

Shifting to the left is the same as multiplying by a power of 

`p`:: 

  

sage: a << 2 

3*5^5 + 5^6 + O(5^20) 

sage: a*5^2 

3*5^5 + 5^6 + O(5^20) 

sage: b << 2 

3*5^5 + 5^6 + O(5^25) 

sage: b*5^2 

3*5^5 + 5^6 + O(5^25) 

  

Shifting by a negative integer to the left is the same as 

right shifting by the absolute value:: 

  

sage: a << -3 

3 + 5 + O(5^17) 

sage: a >> 3 

3 + 5 + O(5^17) 

sage: b << -3 

3 + 5 + O(5^20) 

sage: b >> 3 

3 + 5 + O(5^20) 

""" 

# TODO: move this up the hierarchy, perhaps this should go all the way to element? 

# The "verify that shift is an integer" part could be shared 

cdef long s 

if isinstance(shift, int): 

s = PyInt_AS_LONG(shift) 

else: 

if not isinstance(shift, Integer): 

shift = Integer(shift) 

if mpz_fits_slong_p((<Integer>shift).value) == 0: 

raise ValueError("valuation overflow") 

s = mpz_get_si((<Integer>shift).value) 

check_ordp(s) 

return self._lshift_c(s) 

  

cdef pAdicTemplateElement _lshift_c(self, long shift): 

raise NotImplementedError 

  

def __rshift__(pAdicTemplateElement self, shift): 

""" 

Divides by ``p^shift``, and truncates (if the parent is not a field). 

  

EXAMPLES:: 

  

sage: R = Zp(997, 7, 'capped-abs'); a = R(123456878908); a 

964*997 + 572*997^2 + 124*997^3 + O(997^7) 

sage: S = Zp(5); K = Qp(5); b = S(17); b 

2 + 3*5 + O(5^20) 

  

Shifting to the right divides by a power of `p`, but drops 

terms with negative valuation:: 

  

sage: a >> 3 

124 + O(997^4) 

sage: b >> 1 

3 + O(5^19) 

sage: b >> 40 

O(5^0) 

  

If the parent is a field no truncation is performed:: 

  

sage: K(17) >> 1 

2*5^-1 + 3 + O(5^19) 

  

A negative shift multiplies by that power of `p`:: 

  

sage: a >> -3 

964*997^4 + 572*997^5 + 124*997^6 + O(997^7) 

sage: K(17) >> -5 

2*5^5 + 3*5^6 + O(5^25) 

""" 

cdef long s 

if isinstance(shift, int): 

s = PyInt_AS_LONG(shift) 

else: 

if not isinstance(shift, Integer): 

shift = Integer(shift) 

if mpz_fits_slong_p((<Integer>shift).value) == 0: 

raise ValueError("valuation overflow") 

s = mpz_get_si((<Integer>shift).value) 

check_ordp(s) 

return self._rshift_c(s) 

  

cdef pAdicTemplateElement _rshift_c(self, long shift): 

""" 

Divides by ``p^shift`` and truncates (if the parent is not a field). 

""" 

raise NotImplementedError 

  

cdef int check_preccap(self) except -1: 

""" 

Checks that this element doesn't have precision higher than allowed by 

the precision cap. 

""" 

raise NotImplementedError 

  

def lift_to_precision(self, absprec=None): 

""" 

Returns another element of the same parent with absolute precision at 

least ``absprec``, congruent to this `p`-adic element modulo the 

precision of this element. 

  

INPUT: 

  

- ``absprec`` -- an integer or ``None`` (default: ``None``), the 

absolute precision of the result. If ``None``, lifts to the maximum 

precision allowed. 

  

.. NOTE:: 

  

If setting ``absprec`` that high would violate the precision cap, 

raises a precision error. Note that the new digits will not 

necessarily be zero. 

  

EXAMPLES:: 

  

sage: R = ZpCA(17) 

sage: R(-1,2).lift_to_precision(10) 

16 + 16*17 + O(17^10) 

sage: R(1,15).lift_to_precision(10) 

1 + O(17^15) 

sage: R(1,15).lift_to_precision(30) 

Traceback (most recent call last): 

... 

PrecisionError: Precision higher than allowed by the precision cap. 

sage: R(-1,2).lift_to_precision().precision_absolute() == R.precision_cap() 

True 

  

sage: R = Zp(5); c = R(17,3); c.lift_to_precision(8) 

2 + 3*5 + O(5^8) 

sage: c.lift_to_precision().precision_relative() == R.precision_cap() 

True 

  

Fixed modulus elements don't raise errors:: 

  

sage: R = ZpFM(5); a = R(5); a.lift_to_precision(7) 

5 + O(5^20) 

sage: a.lift_to_precision(10000) 

5 + O(5^20) 

  

""" 

if absprec is None: 

absprec = maxordp 

if not isinstance(absprec, Integer): 

absprec = Integer(absprec) 

if mpz_fits_slong_p((<Integer>absprec).value) == 0: 

raise PrecisionError("Precision higher than allowed by the precision cap") 

ans = self.lift_to_precision_c(mpz_get_si((<Integer>absprec).value)) 

ans.check_preccap() 

return ans 

  

cdef pAdicTemplateElement lift_to_precision_c(self, long absprec): 

""" 

Lifts this element to another with precision at least absprec. 

""" 

raise NotImplementedError 

  

def expansion(self, n = None, lift_mode = 'simple', start_val = None): 

r""" 

Return the coefficients in a `\pi`-adic expansion. 

If this is a field element, start at 

`\pi^{\mbox{valuation}}`, if a ring element at `\pi^0`. 

  

For each lift mode, this function returns a list of `a_i` so 

that this element can be expressed as 

  

.. MATH:: 

  

\pi^v \cdot \sum_{i=0}^\infty a_i \pi^i 

  

where `v` is the valuation of this element when the parent is 

a field, and `v = 0` otherwise. 

  

Different lift modes affect the choice of `a_i`. When 

``lift_mode`` is ``'simple'``, the resulting `a_i` will be 

non-negative: if the residue field is `\mathbb{F}_p` then they 

will be integers with `0 \le a_i < p`; otherwise they will be 

a list of integers in the same range giving the coefficients 

of a polynomial in the indeterminant representing the maximal 

unramified subextension. 

  

Choosing ``lift_mode`` as ``'smallest'`` is similar to 

``'simple'``, but uses a balanced representation `-p/2 < a_i 

\le p/2`. 

  

Finally, setting ``lift_mode = 'teichmuller'`` will yield 

Teichmuller representatives for the `a_i`: `a_i^q = a_i`. In 

this case the `a_i` will lie in the ring of integers of the 

maximal unramified subextension of the parent of this element. 

  

INPUT: 

  

- ``n`` -- integer (default ``None``). If given, returns the corresponding 

entry in the expansion. Can also accept a slice (see :meth:`slice`) 

  

- ``lift_mode`` -- ``'simple'``, ``'smallest'`` or 

``'teichmuller'`` (default: ``'simple'``) 

  

- ``start_val`` -- start at this valuation rather than the 

default (`0` or the valuation of this element). 

  

OUTPUT: 

  

- If ``n`` is ``None``, an iterable giving a `\pi`-adic expansion of this 

element. For base elements the contents will be integers if 

``lift_mode`` is ``'simple'`` or ``'smallest'``, and 

elements of ``self.parent()`` if ``lift_mode`` is 

``'teichmuller'``. 

  

- If ``n`` is an integer, the coefficient of `\pi^n` in the 

`\pi`-adic expansion of this element. 

  

.. NOTE:: 

  

Use slice operators to get a particular range. 

  

EXAMPLES:: 

  

sage: R = Zp(7,6); a = R(12837162817); a 

3 + 4*7 + 4*7^2 + 4*7^4 + O(7^6) 

sage: E = a.expansion(); E 

7-adic expansion of 3 + 4*7 + 4*7^2 + 4*7^4 + O(7^6) 

sage: list(E) 

[3, 4, 4, 0, 4, 0] 

sage: sum([c * 7^i for i, c in enumerate(E)]) == a 

True 

sage: E = a.expansion(lift_mode='smallest'); E 

7-adic expansion of 3 + 4*7 + 4*7^2 + 4*7^4 + O(7^6) (balanced) 

sage: list(E) 

[3, -3, -2, 1, -3, 1] 

sage: sum([c * 7^i for i, c in enumerate(E)]) == a 

True 

sage: E = a.expansion(lift_mode='teichmuller'); E 

7-adic expansion of 3 + 4*7 + 4*7^2 + 4*7^4 + O(7^6) (teichmuller) 

sage: list(E) 

[3 + 4*7 + 6*7^2 + 3*7^3 + 2*7^5 + O(7^6), 

0, 

5 + 2*7 + 3*7^3 + O(7^4), 

1 + O(7^3), 

3 + 4*7 + O(7^2), 

5 + O(7)] 

sage: sum(c * 7^i for i, c in enumerate(E)) 

3 + 4*7 + 4*7^2 + 4*7^4 + O(7^6) 

  

If the element has positive valuation then the list will start 

with some zeros:: 

  

sage: a = R(7^3 * 17) 

sage: E = a.expansion(); E 

7-adic expansion of 3*7^3 + 2*7^4 + O(7^9) 

sage: list(E) 

[0, 0, 0, 3, 2, 0, 0, 0, 0] 

  

The expansion of 0 is truncated:: 

  

sage: E = R(0, 7).expansion(); E 

7-adic expansion of O(7^7) 

sage: len(E) 

0 

sage: list(E) 

[] 

  

In fields, on the other hand, the expansion starts at the valuation:: 

  

sage: R = Qp(7,4); a = R(6*7+7**2); E = a.expansion(); E 

7-adic expansion of 6*7 + 7^2 + O(7^5) 

sage: list(E) 

[6, 1, 0, 0] 

sage: list(a.expansion(lift_mode='smallest')) 

[-1, 2, 0, 0] 

sage: list(a.expansion(lift_mode='teichmuller')) 

[6 + 6*7 + 6*7^2 + 6*7^3 + O(7^4), 

2 + 4*7 + 6*7^2 + O(7^3), 

3 + 4*7 + O(7^2), 

3 + O(7)] 

  

You can ask for a specific entry in the expansion:: 

  

sage: a.expansion(1) 

6 

sage: a.expansion(1, lift_mode='smallest') 

-1 

sage: a.expansion(2, lift_mode='teichmuller') 

2 + 4*7 + 6*7^2 + O(7^3) 

  

TESTS: 

  

Check to see that :trac:`10292` is resolved:: 

  

sage: E = EllipticCurve('37a') 

sage: R = E.padic_regulator(7) 

sage: len(R.expansion()) 

19 

""" 

if isinstance(n, slice): 

return self.slice(n.start, n.stop, n.step, lift_mode=lift_mode) 

  

cdef long shift, prec, val 

cdef expansion_mode mode 

prec = self.precision_relative() 

val = self.valuation_c() 

if prec == 0: 

shift = 0 

elif start_val is not None: 

if n is not None: 

raise ValueError("n and start_val are incompatible options") 

shift = val - start_val 

elif self.prime_pow.in_field: 

shift = 0 

else: 

shift = val 

  

if lift_mode == 'simple': 

mode = simple_mode 

elif lift_mode == 'smallest': 

mode = smallest_mode 

elif lift_mode == 'teichmuller': 

mode = teichmuller_mode 

else: 

raise ValueError("unknown lift_mode") 

  

cdef ExpansionIterable expansion = ExpansionIterable(self, prec, shift, mode) 

if n is None: 

return expansion 

else: 

if n < val: 

return _zero(mode, expansion.teich_ring) 

elif self.prime_pow.in_field: 

return expansion[n - val] 

else: 

return expansion[n] 

  

def list(self, lift_mode = 'simple', start_val = None): 

r""" 

Returns the list of coefficients in a `\pi`-adic expansion of this element. 

  

EXAMPLES:: 

  

sage: R = Zp(7,6); a = R(12837162817); a 

3 + 4*7 + 4*7^2 + 4*7^4 + O(7^6) 

sage: L = a.list(); L 

doctest:warning 

... 

DeprecationWarning: list is deprecated. Please use expansion instead. 

See http://trac.sagemath.org/14825 for details. 

[3, 4, 4, 0, 4, 0] 

  

.. SEEALSO:: 

  

:meth:`expansion` 

  

""" 

deprecation(14825, "list is deprecated. Please use expansion instead.") 

return list(self.expansion(lift_mode=lift_mode, start_val=start_val)) 

  

def teichmuller_expansion(self, n = None): 

r""" 

Returns an iterator over coefficients `a_0, a_1, \dots, a_n` such that 

  

- `a_i^q = a_i`, where `q` is the cardinality of the residue field, 

  

- this element can be expressed as 

  

.. MATH:: 

  

\pi^v \cdot \sum_{i=0}^\infty a_i \pi^i 

  

where `v` is the valuation of this element when the parent is 

a field, and `v = 0` otherwise. 

  

- if `a_i \ne 0`, the precision of `a_i` is `i` less 

than the precision of this element (relative in the case that 

the parent is a field, absolute otherwise) 

  

.. NOTE:: 

  

The coefficients will lie in the ring of integers of the 

maximal unramified subextension. 

  

INPUT: 

  

- ``n`` -- integer (default ``None``). If given, returns the 

coefficient of `\pi^n` in the expansion. 

  

EXAMPLES: 

  

For fields, the expansion starts at the valuation:: 

  

sage: R = Qp(5,5); list(R(70).teichmuller_expansion()) 

[4 + 4*5 + 4*5^2 + 4*5^3 + 4*5^4 + O(5^5), 

3 + 3*5 + 2*5^2 + 3*5^3 + O(5^4), 

2 + 5 + 2*5^2 + O(5^3), 

1 + O(5^2), 

4 + O(5)] 

  

But if you specify ``n``, you get the coefficient of `\pi^n`:: 

  

sage: R(70).teichmuller_expansion(2) 

3 + 3*5 + 2*5^2 + 3*5^3 + O(5^4) 

""" 

return self.expansion(n, lift_mode='teichmuller') 

  

def teichmuller_list(self): 

r""" 

Returns the list of coefficients in the Teichmuller expansion of this element. 

  

EXAMPLES:: 

  

sage: R = Qp(5,5); R(70).teichmuller_list()[1] 

doctest:warning 

... 

DeprecationWarning: teichmuller_list is deprecated. Please use teichmuller_expansion instead. 

See http://trac.sagemath.org/14825 for details. 

3 + 3*5 + 2*5^2 + 3*5^3 + O(5^4) 

  

.. SEEALSO:: 

  

:meth:`teichmuller_expansion` 

  

""" 

deprecation(14825, "teichmuller_list is deprecated. Please use teichmuller_expansion instead.") 

return list(self.teichmuller_expansion()) 

  

def padded_list(self, n, lift_mode = 'simple'): 

""" 

Returns a list of coefficients of the uniformizer `\pi` 

starting with `\pi^0` up to `\pi^n` exclusive (padded with 

zeros if needed). 

  

For a field element of valuation `v`, starts at `\pi^v` 

instead. 

  

INPUT: 

  

- ``n`` - an integer 

  

- ``lift_mode`` - 'simple', 'smallest' or 'teichmuller' 

  

EXAMPLES:: 

  

sage: R = Zp(7,4,'capped-abs'); a = R(2*7+7**2); a.padded_list(5) 

doctest:warning 

... 

DeprecationWarning: padded_list is deprecated. Please use expansion or Integer.digits with the padto keyword instead. 

See http://trac.sagemath.org/14825 for details. 

[0, 2, 1, 0, 0] 

sage: R = Zp(7,4,'fixed-mod'); a = R(2*7+7**2); a.padded_list(5) 

[0, 2, 1, 0, 0] 

  

For elements with positive valuation, this function will 

return a list with leading 0s if the parent is not a field:: 

  

sage: R = Zp(7,3,'capped-rel'); a = R(2*7+7**2); a.padded_list(5) 

[0, 2, 1, 0, 0] 

sage: R = Qp(7,3); a = R(2*7+7**2); a.padded_list(5) 

[2, 1, 0, 0] 

sage: a.padded_list(3) 

[2, 1] 

""" 

deprecation(14825, "padded_list is deprecated. Please use expansion or Integer.digits with the padto keyword instead.") 

L = list(self.expansion(lift_mode=lift_mode)) 

if lift_mode == 'simple' or lift_mode == 'smallest': 

# defined in the linkage file. 

zero = _expansion_zero 

else: 

zero = self.parent()(0,0) 

if self.prime_pow.in_field == 1: 

if self._is_exact_zero(): 

n = 0 

else: 

n -= self.valuation() 

return list(itertools.chain(itertools.islice(L, n), itertools.repeat(zero, n - len(L)))) 

  

def _ext_p_list(self, pos): 

""" 

Returns the p-adic expansion of the unit part. Used in printing. 

  

EXAMPLES:: 

  

sage: R.<a> = Qq(125) 

sage: b = a^2 + 5*a + 1 

sage: b._ext_p_list(True) 

[[1, 0, 1], [0, 1]] 

""" 

if pos: 

return trim_zeros(list(self.unit_part().expansion(lift_mode='simple'))) 

else: 

return trim_zeros(list(self.unit_part().expansion(lift_mode='smallest'))) 

  

cpdef pAdicTemplateElement unit_part(self): 

""" 

Returns the unit part of this element. 

  

This is the `p`-adic element `u` in the same ring so that this 

element is `\pi^v u`, where `\pi` is a uniformizer and `v` is 

the valuation of this element. 

""" 

raise NotImplementedError 

  

cpdef bint _is_base_elt(self, p) except -1: 

""" 

Return ``True`` if this element is an element of Zp or Qp (rather than 

an extension). 

  

INPUT: 

  

- ``p`` -- a prime, which is compared with the parent of this element. 

  

EXAMPLES:: 

  

sage: a = Zp(5)(3); a._is_base_elt(5) 

True 

sage: a._is_base_elt(17) 

False 

  

""" 

return self.prime_pow.prime == p and self.prime_pow.deg == 1 

  

def _prime_pow(self): 

""" 

Provides access to this element's ``prime_pow``. 

  

EXAMPLES:: 

  

sage: R = ZpCR(5,5) 

sage: R(1)._prime_pow() 

PowComputer for 5 

""" 

return self.prime_pow 

  

def residue(self, absprec=1, field=None, check_prec=True): 

r""" 

Reduce this element modulo `p^\mathrm{absprec}`. 

  

INPUT: 

  

- ``absprec`` -- ``0`` or ``1``. 

  

- ``field`` -- boolean (default ``None``). For precision 1, whether to return 

an element of the residue field or a residue ring. Currently unused. 

  

- ``check_prec`` -- boolean (default ``True``). Whether to raise an error if this 

element has insufficient precision to determine the reduction. Errors are never 

raised for fixed-mod or floating-point types. 

  

OUTPUT: 

  

This element reduced modulo `p^\mathrm{absprec}` as an element of the 

residue field or the null ring. 

  

EXAMPLES:: 

  

sage: R.<a> = Zq(27, 4) 

sage: (3 + 3*a).residue() 

0 

sage: (a + 1).residue() 

a0 + 1 

  

TESTS:: 

  

sage: a.residue(0) 

0 

sage: a.residue(2) 

Traceback (most recent call last): 

... 

NotImplementedError: reduction modulo p^n with n>1. 

sage: a.residue(10) 

Traceback (most recent call last): 

... 

PrecisionError: insufficient precision to reduce modulo p^10. 

sage: a.residue(10, check_prec=False) 

Traceback (most recent call last): 

... 

NotImplementedError: reduction modulo p^n with n>1. 

  

sage: R.<a> = ZqCA(27, 4) 

sage: (3 + 3*a).residue() 

0 

sage: (a + 1).residue() 

a0 + 1 

  

sage: R.<a> = Qq(27, 4) 

sage: (3 + 3*a).residue() 

0 

sage: (a + 1).residue() 

a0 + 1 

sage: (a/3).residue() 

Traceback (most recent call last): 

... 

ValueError: element must have non-negative valuation in order to compute residue. 

""" 

if absprec < 0: 

raise ValueError("cannot reduce modulo a negative power of the uniformizer.") 

if self.valuation() < 0: 

raise ValueError("element must have non-negative valuation in order to compute residue.") 

R = self.parent() 

if check_prec and (R.is_fixed_mod() or R.is_floating_point()): 

check_prec = False 

if check_prec and absprec > self.precision_absolute(): 

raise PrecisionError("insufficient precision to reduce modulo p^%s."%absprec) 

if field and absprec != 1: 

raise ValueError("field keyword may only be set at precision 1") 

if absprec == 0: 

from sage.rings.all import IntegerModRing 

return IntegerModRing(1).zero() 

elif absprec == 1: 

parent = R.residue_field() 

if self.valuation() > 0: 

return parent.zero() 

return parent(self.expansion(0)) 

else: 

raise NotImplementedError("reduction modulo p^n with n>1.") 

  

cdef Integer exact_pow_helper(long *ansrelprec, long relprec, _right, PowComputer_ prime_pow): 

""" 

This function is used by exponentiation in both CR_template.pxi 

and CA_template.pxi to determine the extra precision gained from 

an exponent of positive valuation. See __pow__ there and in 

padic_ZZ_pX_CR_element.pyx for more details on this phenomenon. 

  

INPUT: 

  

- ``ansrelprec`` -- (return value) the relative precision of the answer 

  

- ``relprec`` -- a positive integer: the relative precision of the base 

  

- ``_right`` -- the exponent, nonzero 

  

- ``prime_pow`` -- the Powcomputer for the ring. 

  

OUTPUT: 

  

an Integer congruent to the given exponent 

  

""" 

####### NOTE: this function needs to be updated for extension elements. ####### 

cdef Integer right, p = prime_pow.prime 

cdef long exp_val 

cdef bint isbase 

if isinstance(_right, (int, long)): 

_right = Integer(_right) 

if isinstance(_right, Integer): 

right = <Integer> _right 

exp_val = mpz_get_si((<Integer>right.valuation(p)).value) 

elif isinstance(_right, Rational): 

raise NotImplementedError 

ansrelprec[0] = relprec + exp_val 

if exp_val > 0 and mpz_cmp_ui(p.value, 2) == 0 and relprec == 1: 

ansrelprec[0] += 1 

  

return right 

  

cdef long padic_pow_helper(celement result, celement base, long base_val, long base_relprec, 

celement right_unit, long right_val, long right_relprec, PowComputer_ prime_pow) except -1: 

""" 

INPUT: 

  

- ``result`` -- the result of exponentiation. 

  

- ``base`` -- a celement, the base of the exponentiation. 

  

- ``base_val`` -- a long, used to check that the base is a unit 

  

- ``base_relprec`` -- a positive integer: the relative precision 

of the base. 

  

- ``right_unit`` -- the unit part of the exponent 

  

- ``right_val`` -- the valuation of the exponent 

  

- ``right_relprec`` -- the relative precision of the exponent 

  

- ``prime_pow`` -- the Powcomputer for the ring. 

  

OUTPUT: 

  

the precision of the result 

  

EXAMPLES:: 

  

sage: R = Zp(17,print_mode='digits') 

sage: a = R(9283732, 6); b = R(17^3*237, 7) 

sage: str(a) 

'...692AAF' 

sage: str(a^b) # indirect doctest 

'...55GA0001' 

sage: str((a // R.teichmuller(15))^b) 

'...55GA0001' 

sage: str((a.log()*b).exp()) 

'...55GA0001' 

""" 

if base_val != 0: 

raise ValueError("in order to raise to a p-adic exponent, base must be a unit") 

####### NOTE: this function needs to be updated for extension elements. ####### 

cdef celement oneunit, teichdiff 

cdef long loga_val, loga_aprec, bloga_val, bloga_aprec 

cdef Integer expcheck, right 

try: 

cconstruct(oneunit, prime_pow) 

cconstruct(teichdiff, prime_pow) 

cteichmuller(oneunit, base, base_relprec, prime_pow) 

cdivunit(oneunit, base, oneunit, base_relprec, prime_pow) 

csetone(teichdiff, prime_pow) 

csub(teichdiff, oneunit, teichdiff, base_relprec, prime_pow) 

## For extension elements in ramified extensions, the computation of the 

## valuation and precision of log(a) is more complicated) 

loga_val = cvaluation(teichdiff, base_relprec, prime_pow) 

loga_aprec = base_relprec 

# valuation of b*log(a) 

bloga_val = loga_val + right_val 

bloga_aprec = bloga_val + min(right_relprec, loga_aprec - loga_val) 

if bloga_aprec > prime_pow.ram_prec_cap: 

bloga_aprec = prime_pow.ram_prec_cap 

expcheck = PY_NEW(Integer) 

mpz_sub_ui(expcheck.value, prime_pow.prime.value, 1) 

mpz_mul_si(expcheck.value, expcheck.value, bloga_val) 

if mpz_cmp_ui(expcheck.value, prime_pow.e) <= 0: 

raise ValueError("exponential does not converge") 

right = PY_NEW(Integer) 

try: 

cconv_mpz_t_out(right.value, right_unit, right_val, right_relprec, prime_pow) 

except ValueError: 

# Here we need to use the exp(b log(a)) definition, 

# since we can't convert the exponent to an integer 

raise NotImplementedError("exponents with negative valuation not yet supported") 

## For extension elements in ramified extensions 

## the following precision might need to be changed. 

cpow(result, oneunit, right.value, bloga_aprec, prime_pow) 

finally: 

cdestruct(oneunit, prime_pow) 

cdestruct(teichdiff, prime_pow) 

return bloga_aprec 

  

cdef _zero(expansion_mode mode, teich_ring): 

""" 

Return an appropriate zero for a given expansion mode. 

  

INPUT: 

  

- ``mode`` -- either ``simple_mode`` or ``smallest_mode`` or ``teichmuller_mode`` 

- ``teich_ring`` -- the integer ring of the maximal unramified subextension 

of the parent. Only used in ``teichmuller_mode``. 

""" 

if mode == teichmuller_mode: 

return teich_ring(0) 

else: 

return _expansion_zero 

  

cdef class ExpansionIter(object): 

""" 

An iterator over a `p`-adic expansion. 

  

This class should not be instantiated directly, but instead using :meth:`expansion`. 

  

INPUT: 

  

- ``elt`` -- the `p`-adic element 

- ``prec`` -- the number of terms to be emitted 

- ``mode`` -- either ``simple_mode``, ``smallest_mode`` or ``teichmuller_mode`` 

  

EXAMPLES:: 

  

sage: E = Zp(5,4)(373).expansion() 

sage: I = iter(E) # indirect doctest 

sage: type(I) 

<type 'sage.rings.padics.padic_capped_relative_element.ExpansionIter'> 

""" 

cdef pAdicTemplateElement elt 

cdef celement tmp 

cdef celement curvalue 

cdef long curpower 

cdef bint tracks_prec 

cdef expansion_mode mode 

cdef object teich_ring 

  

def __cinit__(self, pAdicTemplateElement elt, long prec, expansion_mode mode): 

""" 

Allocates memory for the iterator. 

  

TESTS:: 

  

sage: E = Zp(5,4)(373).expansion() 

sage: I = iter(E) 

sage: next(I) 

3 

""" 

self.elt = elt 

self.curpower = prec 

self.mode = mode 

if mode == teichmuller_mode: 

R = elt.parent() 

self.tracks_prec = R.is_capped_relative() or R.is_capped_absolute() 

self.teich_ring = R.maximal_unramified_subextension().integer_ring() 

cconstruct(self.tmp, elt.prime_pow) 

cconstruct(self.curvalue, elt.prime_pow) 

elt._get_unit(self.curvalue) 

  

def __dealloc__(self): 

""" 

Deallocates memory for the iterator. 

  

TESTS:: 

  

sage: E = Zp(5,4)(373).expansion() 

sage: I = iter(E) 

sage: del I 

""" 

cdestruct(self.tmp, self.elt.prime_pow) 

cdestruct(self.curvalue, self.elt.prime_pow) 

  

def __iter__(self): 

""" 

Chracteristic property of an iterator: ``__iter__`` returns itself. 

  

TESTS:: 

  

sage: E = Zp(5,4)(373).expansion() 

sage: I = iter(E) 

sage: I is iter(I) 

True 

""" 

return self 

  

def __len__(self): 

""" 

Returns the number of terms that will be emitted. 

  

TESTS:: 

  

sage: E = Zp(5,4)(373).expansion() 

sage: I = iter(E) 

sage: len(I) 

4 

sage: c = next(I); len(I) 

3 

""" 

return self.curpower 

  

def __next__(self): 

""" 

Provides the next coefficient in the `p`-adic expansion. 

  

EXAMPLES:: 

  

sage: E = Zp(5,4)(373).expansion() 

sage: I = iter(E) 

sage: next(I) 

3 

sage: next(I), next(I), next(I) 

(4, 4, 2) 

""" 

if self.curpower <= 0: 

raise StopIteration 

self.curpower -= 1 

cdef pAdicTemplateElement ans 

cdef PowComputer_ pp = self.elt.prime_pow 

cdef long prec 

if ciszero(self.curvalue, pp): 

return _zero(self.mode, self.teich_ring) 

if self.mode == teichmuller_mode: 

prec = self.curpower+1 if self.tracks_prec else pp.ram_prec_cap 

cteichmuller(self.tmp, self.curvalue, prec, pp) 

if ciszero(self.tmp, pp): 

cshift_notrunc(self.curvalue, self.curvalue, -1, prec-1, pp) 

return _zero(teichmuller_mode, self.teich_ring) 

else: 

csub(self.curvalue, self.curvalue, self.tmp, prec, pp) 

cshift_notrunc(self.curvalue, self.curvalue, -1, prec-1, pp) 

creduce(self.curvalue, self.curvalue, prec-1, pp) 

return self.teich_ring(self.elt._new_with_value(self.tmp, prec)) 

else: 

return cexpansion_next(self.curvalue, self.mode, self.curpower, pp) 

  

cdef class ExpansionIterable(object): 

""" 

An iterable storing a `p`-adic expansion of an element. 

  

This class should not be instantiated directly, but instead using :meth:`expansion`. 

  

INPUT: 

  

- ``elt`` -- the `p`-adic element 

- ``prec`` -- the number of terms to be emitted 

- ``val_shift`` -- how many zeros to add at the beginning of the expansion, 

or the number of initial terms to truncate (if negative) 

- ``mode`` -- either ``simple_mode``, ``smallest_mode`` or ``teichmuller_mode`` 

  

EXAMPLES:: 

  

sage: E = Zp(5,4)(373).expansion() # indirect doctest 

sage: type(E) 

<type 'sage.rings.padics.padic_capped_relative_element.ExpansionIterable'> 

""" 

cdef pAdicTemplateElement elt 

cdef celement tmp 

cdef long prec 

cdef long val_shift 

cdef expansion_mode mode 

cdef object teich_ring 

  

def __cinit__(self, pAdicTemplateElement elt, long prec, long val_shift, expansion_mode mode): 

""" 

Allocates memory for the iteratable. 

  

TESTS:: 

  

sage: Zp(5,4)(373).expansion() 

5-adic expansion of 3 + 4*5 + 4*5^2 + 2*5^3 + O(5^4) 

""" 

self.elt = elt 

cconstruct(self.tmp, elt.prime_pow) 

self.prec = prec 

self.val_shift = val_shift 

self.mode = mode 

if mode == teichmuller_mode: 

self.teich_ring = elt.parent().maximal_unramified_subextension().integer_ring() 

  

def __dealloc__(self): 

""" 

Deallocates memory for the iteratable. 

  

TESTS:: 

  

sage: E = Zp(5,4)(373).expansion() 

sage: del E 

""" 

cdestruct(self.tmp, self.elt.prime_pow) 

  

def __iter__(self): 

""" 

Returns an iterator, based on a corresponding :class:`ExpansionIter`. 

  

If ``val_shift`` is positive, will first emit that many zeros 

(of the appropriate type: ``[]`` instead when the inertia degree 

is larger than one. 

  

If ``val_shift`` is negative, will truncate that many terms at 

the start of the expansion. 

  

EXAMPLES:: 

  

sage: E = Zp(5,4)(373).expansion() 

sage: type(iter(E)) 

<type 'sage.rings.padics.padic_capped_relative_element.ExpansionIter'> 

sage: E = Zp(5,4)(373).expansion(start_val=-1) 

sage: type(iter(E)) 

<type 'itertools.chain'> 

sage: E = Zp(5,4)(373).expansion(start_val=1) 

sage: type(iter(E)) 

<type 'itertools.islice'> 

""" 

cdef ExpansionIter expansion = ExpansionIter(self.elt, self.prec, self.mode) 

if self.val_shift == 0: 

return expansion 

elif self.val_shift < 0: 

return itertools.islice(expansion, -self.val_shift, None) 

else: 

return itertools.chain(itertools.repeat(_zero(self.mode, self.teich_ring), self.val_shift), expansion) 

  

def __len__(self): 

""" 

Returns the number of terms that will be emitted. 

  

TESTS:: 

  

sage: len(Zp(5,4)(373).expansion()) 

4 

sage: len(Zp(5,4)(373).expansion(start_val=-1)) 

5 

sage: len(Zp(5,4)(373).expansion(start_val=1)) 

3 

sage: len(Zp(5,4)(0).expansion()) 

0 

""" 

return self.prec + self.val_shift 

  

def __getitem__(self, n): 

""" 

Return the ``n``th entry in the expansion. 

  

Negative indices are not allowed. 

  

EXAMPLES:: 

  

sage: E = Zp(5,4)(373).expansion() 

sage: E[0] 

3 

sage: E[3] 

2 

sage: list(E[::2]) 

[3, 4] 

sage: a = E[-1] 

Traceback (most recent call last): 

... 

ValueError: Negative indices not supported 

sage: Zp(5,4)(373).expansion(lift_mode='smallest')[3] 

-2 

""" 

if isinstance(n, slice): 

return itertools.islice(iter(self), n.start, n.stop, n.step) 

cdef long m = n - self.val_shift 

cdef celement value 

if n < 0: 

raise ValueError("Negative indices not supported") 

elif m < 0: 

return _zero(self.mode, self.teich_ring) 

elif m >= self.prec: 

raise PrecisionError 

elif self.mode == simple_mode: 

self.elt._get_unit(self.tmp) 

return cexpansion_getitem(self.tmp, m, self.elt.prime_pow) 

else: 

expansion = ExpansionIter(self.elt, self.prec, self.mode) 

# We do this in a naive way, though it should be feasible 

# to implement something better for smallest_mode 

return next(itertools.islice(expansion, m, m+1)) 

  

def __repr__(self): 

""" 

String representation. 

  

EXAMPLES:: 

  

sage: Zp(5,4)(373).expansion() 

5-adic expansion of 3 + 4*5 + 4*5^2 + 2*5^3 + O(5^4) 

sage: Zp(5,4)(373).expansion(lift_mode='smallest') 

5-adic expansion of 3 + 4*5 + 4*5^2 + 2*5^3 + O(5^4) (balanced) 

sage: Zp(5,4)(373).expansion(lift_mode='teichmuller') 

5-adic expansion of 3 + 4*5 + 4*5^2 + 2*5^3 + O(5^4) (teichmuller) 

""" 

if self.mode == simple_mode: 

modestr = "" 

elif self.mode == smallest_mode: 

modestr = " (balanced)" 

else: 

modestr = " (teichmuller)" 

p = self.elt.prime_pow.prime 

return "%s-adic expansion of %s%s"%(p, self.elt, modestr)