1 #include "field.h"
2
3 #include <memory>
4 #include <assert.h>
5 #include <cstdio> /* Always include cstdio before gmp.h.*/
6 #include <gmp.h>
7
8 #include "printer.h"
9 #include "log.h"
10 #include "myassert.h"
11
12 // The following macro is used for logging of field creation. Note that the usual "log1" does not work since the logLevel might not be initialized at the point of field construction
13 #define flog1 if(0)
14 #define flog2 if(0)
15
16
FieldElement(Field const & f)17 FieldElement::FieldElement(Field const &f)
18 #if USESHAREDPTR
19 :
20 // theField(f)
21 implementingObject(f.zHomomorphismImplementation(0))
22 #endif
23 {
24 assert(f.implementingObject);
25 #if !USESHAREDPTR
26 implementingObject=f.zHomomorphismImplementation(0);//create object with refCount 1
27 #endif
28 // f.implementingObject->refCount++;
29 flog2 fprintf(Stderr,"FieldElement - constructing1\n");
30 }
31
FieldElement(class FieldElementImplementation * implementingObject_)32 FieldElement::FieldElement(class FieldElementImplementation *implementingObject_):
33 implementingObject(implementingObject_)
34 {
35 }
36
FieldElement(const FieldElement & a)37 FieldElement::FieldElement(const FieldElement &a)
38 // theField(a.theField)
39 {
40 // assert(a.implementingObject);
41 if(USESHAREDPTR||a.implementingObject)
42 {
43 implementingObject=a.implementingObject;
44 #if !USESHAREDPTR
45 implementingObject->refCount++;
46 #endif
47 }
48 else
49 { //this constructor is called implicitly in splitPoly
50 // assert(0);
51 implementingObject=0;
52 }
53 flog2 fprintf(Stderr,"FieldElement - constructing2\n");
54 }
55
56 /*int FieldElement::getIntegerRepresentation()const
57 {
58 return implementingObject->getIntegerRepresentation();
59 }*/
60
61
getGmpRationalTemporaryPointer() const62 mpq_t const *FieldElement::getGmpRationalTemporaryPointer()const
63 {
64 return (implementingObject)->getGmpRationalTemporaryPointer();
65 }
66
67
floatingPointApproximation() const68 double FieldElement::floatingPointApproximation()const
69 {
70 mpq_t const *p=getGmpRationalTemporaryPointer();
71
72 return mpq_get_d(*p);//LEAK??
73 }
74
75
isInteger() const76 bool FieldElement::isInteger()const
77 {
78 return implementingObject->isInteger();
79 }
80
81
multiplierGivingInteger() const82 FieldElement FieldElement::multiplierGivingInteger()const
83 {
84 return FieldElement(implementingObject->multiplierGivingInteger());
85 }
86
87
~FieldElement()88 FieldElement::~FieldElement()
89 {
90 #if !USESHAREDPTR
91 if(implementingObject && 0==(--(implementingObject->refCount)))
92 {
93 //implementingObject->refCount=0x8000;
94 delete implementingObject;
95 // fprintf(Stderr,"DELETE\n");
96 flog2 fprintf(Stderr,"Deleting implementing object\n");
97 }
98 #endif
99
100 flog2 fprintf(Stderr,"FieldElement - destructing\n");
101 }
102
operator =(const FieldElement & a)103 FieldElement& FieldElement::operator=(const FieldElement& a)
104 {
105 #if !USESHAREDPTR
106 if(this==&a)
107 {
108 flog2 fprintf(Stderr,"FieldElement - selfassignment\n");
109
110 return *this;
111 }
112 if(implementingObject&& 0==(--(implementingObject->refCount)))
113 {
114 delete implementingObject;
115 // fprintf(Stderr,"DELETE\n");
116 flog2 fprintf(Stderr,"FieldElement - deleting old implementing\n");
117 }
118 //assert(a.implementingObject);
119 if(a.implementingObject)
120 {
121 implementingObject=a.implementingObject;
122 implementingObject->refCount++;
123 }
124 else
125 {
126 implementingObject=0;
127 }
128 #else
129 implementingObject=a.implementingObject;
130 #endif
131 flog2 fprintf(Stderr,"FieldElement - assignment\n");
132 return *this;
133 }
134
getField() const135 class FieldImplementation *FieldElement::getField()const
136 {
137 // debug<<"getField()\n";
138 FieldImplementation *r=implementingObject->getField();
139 // debug<<"getField()\n";
140 return r;
141 }
142
one() const143 FieldElement FieldElement::one() const//change this implementation
144 {
145 assert(implementingObject);
146 return FieldElement(implementingObject->one());
147 }
148
149
isZero() const150 bool FieldElement::isZero()const
151 {
152 assert(implementingObject);
153 return implementingObject->isZero();
154 }
155
isOne() const156 bool FieldElement::isOne()const
157 {
158 if(!implementingObject)return false;
159 return (*this-one()).isZero();
160 }
161
162
operator +(const FieldElement & a,const FieldElement & b)163 FieldElement operator+(const FieldElement &a,const FieldElement &b)
164 {
165 assert(a.implementingObject);
166 assert(b.implementingObject);
167 return FieldElement(a.implementingObject->sum(*(b.implementingObject)));
168 }
169
170
operator -(const FieldElement & a,const FieldElement & b)171 FieldElement operator-(const FieldElement &a,const FieldElement &b)
172 {
173 assert(a.implementingObject);
174 assert(b.implementingObject);
175 return FieldElement(a.implementingObject->difference(*(b.implementingObject)));
176 }
177
operator -(const FieldElement & b)178 FieldElement operator-(const FieldElement &b)
179 {
180 assert(b.implementingObject);
181 return FieldElement(b.implementingObject->negation());
182 }
inverse() const183 FieldElement FieldElement::inverse()const
184 {
185 assert(implementingObject);
186 return FieldElement(implementingObject->inverse());
187 }
188
sign() const189 int FieldElement::sign()const
190 {
191 assert(implementingObject);
192 return implementingObject->sign();
193 }
194
195
pAdicValuation(int p) const196 int FieldElement::pAdicValuation(int p)const
197 {
198 assert(implementingObject);
199 return implementingObject->pAdicValuation(p);
200 }
201
202
pAdicRemainder(class Field const & ZModPZ) const203 FieldElement FieldElement::pAdicRemainder(class Field const &ZModPZ)const
204 {
205 assert(implementingObject);
206 return FieldElement(implementingObject->pAdicRemainder(ZModPZ));
207 }
208
209
modularRepresentative(class Field const & ZModPZ) const210 FieldElement FieldElement::modularRepresentative(class Field const &ZModPZ)const
211 {
212 assert(implementingObject);
213 return FieldElement(implementingObject->modularRepresentative(ZModPZ));
214 }
215
getIntegerRepresentation() const216 int FieldElement::getIntegerRepresentation()const
217 {
218 assert(implementingObject);
219 return implementingObject->getIntegerRepresentation();
220 }
221
toString(bool writeIfOne,bool alwaysWriteSign,bool latexMode) const222 std::string FieldElement::toString(bool writeIfOne, bool alwaysWriteSign, bool latexMode) const
223 {
224 assert(implementingObject);
225 return implementingObject->toString(writeIfOne,alwaysWriteSign,latexMode);
226 }
227
228 #if USESHAREDPTR
makeUnique()229 void FieldElement::makeUnique()
230 {
231 // if(implementingObject->refCount!=1)
232 if(implementingObject.use_count()!=1)
233 {
234 std::shared_ptr<class FieldElementImplementation> temp(implementingObject->copy());
235 swap(temp,implementingObject);
236 }
237 }
238 #endif
239
operator *=(const FieldElement & a)240 void FieldElement::operator*=(const FieldElement &a)
241 {
242 assert(a.implementingObject);
243 assert(implementingObject);
244 #if !USESHAREDPTR
245 if(implementingObject->refCount!=1)
246 {
247 implementingObject->refCount--;
248 implementingObject=implementingObject->copy();
249 }
250 #else
251 makeUnique();
252 #endif
253 (*implementingObject)*=(*a.implementingObject);
254 }
255
256
operator +=(const FieldElement & a)257 void FieldElement::operator+=(const FieldElement &a)
258 {
259 assert(a.implementingObject);
260 assert(implementingObject);
261 #if !USESHAREDPTR
262 if(implementingObject->refCount!=1)
263 {
264 implementingObject->refCount--;
265 implementingObject=implementingObject->copy();
266 }
267 #else
268 makeUnique();
269 #endif
270 (*implementingObject)+=(*a.implementingObject);
271 }
272
273
madd(const FieldElement & a,const FieldElement & b)274 void FieldElement::madd(const FieldElement &a, const FieldElement &b)
275 {
276 assert(a.implementingObject);
277 assert(b.implementingObject);
278 assert(implementingObject);
279 #if !USESHAREDPTR
280 if(implementingObject->refCount!=1)
281 {
282 implementingObject->refCount--;
283 implementingObject=implementingObject->copy();
284 }
285 #else
286 makeUnique();
287 #endif
288 (*implementingObject).madd(*a.implementingObject,*b.implementingObject);
289 }
290
291
operator *(const FieldElement & a,const FieldElement & b)292 FieldElement operator*(const FieldElement &a,const FieldElement &b)
293 {
294 FieldElement c=a;
295 c*=b;
296 return c;
297 }
298
299
300
301
302
303
304
zHomomorphism(int n) const305 FieldElement Field::zHomomorphism(int n)const
306 {
307 return implementingObject->zHomomorphism(n);
308 }
309
310
random() const311 FieldElement Field::random()const
312 {
313 return implementingObject->random();
314 }
315
316
getCharacteristic() const317 int Field::getCharacteristic()const
318 {
319 return implementingObject->getCharacteristic();
320 }
321
322
323
FieldElementImplementation(FieldImplementation & a)324 FieldElementImplementation::FieldElementImplementation(FieldImplementation &a):
325 #if !USESHAREDPTR
326 refCount(1),
327 #endif
328 theFieldImplementation(a)
329 {
330 #if !USESHAREDPTR
331 a.refCount++;
332 #endif
333 numberOfLivingFieldElementImplementations++;
334 };
335
~FieldElementImplementation()336 FieldElementImplementation::~FieldElementImplementation()
337 {
338 numberOfLivingFieldElementImplementations--;
339 #if !USESHAREDPTR
340 if(0==(--(theFieldImplementation.refCount)))
341 {
342 delete &theFieldImplementation;//NOW THE REFERENCE IS INVALID....
343 flog2 fprintf(Stderr,"Deleting field implementation\n");
344 }
345 #endif
346 };
347
getField() const348 class FieldImplementation *FieldElementImplementation::getField()const
349 {
350 return &theFieldImplementation;
351 }
352
353 /*class Field FieldElementImplementation::getField2()const
354 {
355 return this->t
356 }*/
357
zHomomorphismImplementation(int n) const358 FieldElementImplementation *Field::zHomomorphismImplementation(int n)const
359 {
360 return implementingObject->zHomomorphismImplementation(n);
361 }
362
name()363 const char *Field::name()
364 {
365 return implementingObject->name();
366 }
367
368
isRationals() const369 bool Field::isRationals()const
370 {
371 return implementingObject->isRationals();
372 }
373
toString() const374 std::string Field::toString()const{
375 return implementingObject->toString();
376 }
377
Field(FieldImplementation * implObj)378 Field::Field(FieldImplementation *implObj)
379 #if USESHAREDPTR
380 :
381 implementingObject(implObj)
382 #endif
383 {
384 #if !USESHAREDPTR
385 implObj->refCount++;
386 implementingObject=implObj;
387 #endif
388 flog1 fprintf(Stderr,"Constructing Field %s\n",toString().c_str());
389 flog1 dumpStackTrace();
390 }
391
~Field()392 Field::~Field()
393 {
394 assert(implementingObject);
395 #if !USESHAREDPTR
396 implementingObject->refCount--;
397 assert(implementingObject->refCount>=0);
398 if(implementingObject->refCount==0)
399 {
400 flog1 fprintf(Stderr,"Deleting implementing object\n");
401 delete implementingObject;
402 }
403 implementingObject=0;
404 #endif
405 flog1 fprintf(Stderr,"Destructing Field\n");
406 }
407
Field(Field const & a)408 Field::Field(Field const &a)//copy constructor
409 :implementingObject(a.implementingObject)
410 {
411 #if !USESHAREDPTR
412 implementingObject->refCount++;
413 #endif
414 flog1 fprintf(Stderr,"Copying field\n");
415 }
416
417
operator =(const Field & a)418 Field& Field::operator=(const Field& a)
419 {
420 // assert(0);
421 flog1 fprintf(Stderr,"Assigning Field\n");
422 #if !USESHAREDPTR
423 if(this==&a)
424 {
425 flog1 fprintf(Stderr,"---selfassigning\n");
426 return *this;
427 }
428
429 if(implementingObject&& 0==(--(implementingObject->refCount)))
430 {
431 debug<<"DELETING IMPLEMENTING OBJECT\n";
432 delete implementingObject;
433 }
434 //assert(a.implementingObject);
435 if(a.implementingObject)
436 {
437 implementingObject=a.implementingObject;
438 implementingObject->refCount++;
439 }
440 else
441 implementingObject=0;
442 #else
443 implementingObject=a.implementingObject;
444 #endif
445 return *this;
446 }
447
448 //Field *Field::list;
449 //Field *Field::currentField;
450
451
452 //Field::Field()
453 //{
454 /* if(addToList)
455 {
456 next=list;
457 list=this;
458 }
459 */
460 //}
461
462
463
464 /*Field *Field::find(const char *name)
465 {
466 Field *l=list;
467 while(l)
468 {
469 fprintf(Stderr,"testC\n");
470
471 if(std::string(l->name())==std::string(name))break;
472 l=l->next;
473 }
474 fprintf(Stderr,"testD\n");
475 return l;
476 }
477 */
478 /*
479 void Field::printList(FILE *f)
480 {
481 fprintf(f,"List of linked field classes:\n");
482 Field *l=list;
483 while(l)
484 {
485 fprintf(f," %s\n",l->name());
486 l=l->next;
487 }
488 }
489 */
490
491 /*void Field::checkInitialized()
492 {
493 if(!currentField)
494 {
495 fprintf(Stderr,"test2323\n");
496 setField(find("GmpRationals"));
497 }
498 }
499 */
500
501 /*void Field::setField(Field *field)
502 {
503 assert(field);
504 currentField=field;
505 fprintf(Stderr,"Field class being used: \"%s\".\n",currentField->name());
506 }*/
507
508
509 /*FieldElement Field::staticZHomomorphism(int n)
510 {
511 fprintf(Stderr,"test");
512 // checkInitialized();
513 return currentField->zHomomorphism(n);
514 }*/
515
516
517
518
519
520
521
522
523
524 int FieldImplementation::numberOfLivingFieldImplementations;
525 int FieldElementImplementation::numberOfLivingFieldElementImplementations;
526