4
#include "gfanapplication.h"
6
#include "field_rationals.h"
7
#include "buchberger.h"
9
class RealRootsApplication : public GFanApplication
12
PolynomialSet sturmPolynomials(Polynomial f1)
14
Polynomial f2=f1.derivative();
16
PolynomialRing theRing=f1.getRing();
17
PolynomialSet result(theRing);
22
PolynomialSet g(theRing);
25
g.markAndScale(LexicographicTermOrder());
26
f2=(f1-f1)-division(f1,g,LexicographicTermOrder());
34
int numberOfSignChangesAtMinusInfinity(PolynomialSet const &l)
38
for(PolynomialSet::const_iterator i=l.begin();i!=l.end();i++)
41
p.mark(LexicographicTermOrder());
42
int newSign=p.getMarked().c.sign()*(1-2*(p.getMarked().m.exponent[0]&1));
43
if(newSign && (newSign!=sign))
53
int numberOfSignChangesAtInfinity(PolynomialSet const &l)
57
for(PolynomialSet::const_iterator i=l.begin();i!=l.end();i++)
60
p.mark(LexicographicTermOrder());
61
int newSign=p.getMarked().c.sign();
62
if(newSign && (newSign!=sign))
72
int numberOfSignChanges(PolynomialSet const &l, FieldElement const &a)
76
for(PolynomialSet::const_iterator i=l.begin();i!=l.end();i++)
78
FieldElement v=i->evaluate(a);
80
if(newSign && (newSign!=sign))
90
* Returns a negative number less than all roots of the polynomial whose Sturm sequence is given.
92
FieldElement lowerBoundForRoots(PolynomialSet const &l)
94
FieldElement ret=Q.zHomomorphism(-1);
95
while(numberOfSignChangesAtMinusInfinity(l)!=numberOfSignChanges(l,ret))ret*=Q.zHomomorphism(2);
96
return ret-Q.zHomomorphism(1);
99
FieldElement upperBoundForRoots(PolynomialSet const &l)
101
FieldElement ret=Q.zHomomorphism(1);
102
while(numberOfSignChangesAtInfinity(l)!=numberOfSignChanges(l,ret))ret*=Q.zHomomorphism(2);
103
return ret+Q.zHomomorphism(1);
106
list<FieldElement> intervals(PolynomialSet const &l)
108
list<FieldElement> ret;
109
FieldElement lo(lowerBoundForRoots(l));
114
FieldElement hi=upperBoundForRoots(l);
115
int cLo=numberOfSignChanges(l,lo);
116
int cHi=numberOfSignChanges(l,hi);
121
FieldElement med=(hi+lo)*Q.zHomomorphism(2).inverse();
122
int cMed=numberOfSignChanges(l,med);
142
list<FieldElement> narrow(PolynomialSet const &l, list<FieldElement> intervals, FieldElement epsilon)
144
list<FieldElement> ret;
146
for(list<FieldElement>::const_iterator i=intervals.begin();i!=intervals.end();i++)
148
FieldElement lo=*i;i++;
151
while((hi-lo-epsilon).sign()>0)
153
FieldElement med=(hi+lo)*Q.zHomomorphism(2).inverse();
154
if(numberOfSignChanges(l,med)==numberOfSignChanges(l,hi))
165
//Returns a length that fist in between any two consequtive intervals
166
FieldElement smallestDistance(list<FieldElement> intervals)
168
FieldElement ret=Q.zHomomorphism(1000);
169
if(intervals.size()>=4)
171
list<FieldElement>::const_iterator i=intervals.begin();
173
for(;i!=intervals.end();i++)
175
FieldElement a=*i;i++;
176
FieldElement diff=*i-a;
177
if((diff-ret).sign()<0)ret=diff;
182
/*int numberOfRootsBetweenMinusInfinityAndHere(FieldElement )
187
bool includeInDefaultInstallation()
191
const char *helpText()
193
return "Not working yet. Given generators for a zero-dimensional ideal this program will compute all real points on the variety.\n";
195
RealRootsApplication() {
206
PolynomialSet g=P.parsePolynomialSetWithRing();
207
PolynomialRing r=g.getRing();
208
int n=r.getNumberOfVariables();
209
// Polynomial f1=P.parsePolynomialWithRing();
210
WeightReverseLexicographicTermOrder T(IntegerVector::allOnes(n));
213
int d=krullDimension(g);
216
debug<<"Input ideal is not zero-dimensional.\n";
220
PolynomialRing r2(r.getField(),1);
221
PolynomialSet projectionPolys(r2);
225
LexicographicTermOrder T((i+1)%n);
233
PolynomialSet intersection=g.polynomialRingIntersection(r2,&l);
234
assert(intersection.size()==1);
235
projectionPolys.push_back(*intersection.begin());
237
debug<<projectionPolys;
239
PolynomialSetList sturmPolys;
240
for(PolynomialSet::const_iterator i=projectionPolys.begin();i!=projectionPolys.end();i++)
242
sturmPolys.push_back(sturmPolynomials(*i));
244
debug.printPolynomialSetList(sturmPolys);
247
FieldElement bound=Q.zHomomorphism(1);
248
FieldElement distance=Q.zHomomorphism(1);
249
for(PolynomialSetList::const_iterator i=sturmPolys.begin();i!=sturmPolys.end();i++)
251
debug<<"Lower "<< lowerBoundForRoots(*i)<<"\n";
252
debug<<"Upper "<< upperBoundForRoots(*i)<<"\n";
253
debug<<"Sign changes "<< numberOfSignChangesAtMinusInfinity(*i)<<"\n";
254
FieldElement s=Q.zHomomorphism(-10000);
255
debug<<"Sign changes "<< numberOfSignChanges(*i,s)<<"\n";
256
FieldElement t=Q.zHomomorphism(100000);
257
debug<<"Sign changes "<< numberOfSignChanges(*i,t)<<"\n";
258
debug<<"Sign changes "<< numberOfSignChangesAtInfinity(*i)<<"\n";
260
list<FieldElement> l=intervals(*i);
261
FieldElement epsilon=(upperBoundForRoots(*i)-lowerBoundForRoots(*i))*Q.zHomomorphism(100).inverse();
262
l=narrow(*i,l,epsilon);
265
for(list<FieldElement>::const_iterator j=l.begin();j!=l.end();j++)
266
debug<<*j<<" "<< fieldElementToFloatingPoint(*j)<<"\n";
268
FieldElement b=upperBoundForRoots(*i)-lowerBoundForRoots(*i);
269
// if(bound<b)bound=b;
270
// FieldElement d=smallestDistance(l);
271
// if(d<distance)distance=d;
274
FieldElement epsilon2=distance/bound; //<------------------fix this
275
l=narrow(*i,l,epsilon);
277
FieldElement delta=epsilon/bound;//<--------------------fix this
279
PolynomialRing r3=r.withVariablesAppended("W");
280
Polynomial f=-r3.ithVariable(n);
281
FieldElement multiplier=Q.zHomomorphism(1);
284
f+=multiplier*r3.ithVariable(i);
287
PolynomialSet g2=g.embeddedInto(r3);
292
/* FieldRationalFunctions k(r.getField(),"t");
293
PolynomialRing r2(k,n+1);
294
Polynomial generic(r2)=-r2.ithVariable(n);
296
generic+=k.exponent(i)*r2.ithVariable(i);
298
PolynomialSet g2(r2);
299
g2.push_back(generic);
301
for(PolynomialSet::const_iterator i=g.begin();i!=g.end();i++)
304
for(TermMap::const_iterator j=g.begin();j!=g.end();j++)
306
f+=Term(k.fromCoefficientField(),Monomial(r2,j->first.m.v));
311
LexicographicTermOrder T2;
314
for(PolynomialSet::const_iterator i=g2.begin();i!=g2.end();i++)
316
if(i->numberOfVariablesInUseConsecutive()==1)p=*i;
319
PolynomialRing r3(k,1);
325
//AsciiPrinter(Stdout).printPolynomialSet(result);
327
/* if(evaluateOption.getValue())
329
IntegerVector v=P.parseIntegerVector();
330
for(int i=0;i<v.size();i++)
332
FieldElement x=Q.zHomomorphism(v[i]);
333
AsciiPrinter(Stdout).printString("Evaluating in ");
334
AsciiPrinter(Stdout).printFieldElement(x);
335
AsciiPrinter(Stdout).printNewLine();
336
for(PolynomialSet::const_iterator j=result.begin();j!=result.end();j++)
338
AsciiPrinter(Stdout).printFieldElement(j->evaluate(x));
339
AsciiPrinter(Stdout).printNewLine();
348
static RealRootsApplication theApplication;