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