Z := IntegerRing();

//SetVerbose("ComplexRoots", 1); log("/tmp/l");

procedure test_roots(f, p, eps)
    printf "Test roots; f deg: %o, p: %o, eps: %.1o\n", Degree(f), p, eps;
    IndentPush();
    C<i> := ComplexField(p);
    time R := Roots(f, C);
    for t in R do
	no := Norm(Evaluate(f, t[1]));
	if no gt eps then
	    printf "Bad root norm: %.3o, %.3o\n", no, eps;
	end if;
    end for;
    IndentPop();
end procedure;

test_roots_d := proc<f, p, d | test_roots(f, p, 10.0^-(2*p-d))>;

// Complex roots
P<x> := PolynomialRing(Z);

f := x^6 + x^2 + 2;
"\nDeflation";
test_roots(f, 30, 10.0^-30);
test_roots(f, 50, 10.0^-30);


f :=
12168241813253942553691806693070497447060441024156*x^2 - 
    477269777465393302055454626607396073752055880498*x + 
    4679937413672934196056482740618547834304519423;
"\nClose 1";
test_roots(f, 30, 10.0^-30);
test_roots(f, 50, 10.0^-30);

f :=
58402294605638046321422380894906046130*x^2 + 
    439849947208870206459245032689044388561*x + 
    828169412546373124378473825535720490113;
"\nClose 2";
test_roots(f, 30, 10.0^-30);
test_roots(f, 50, 10.0^-30);

for p in [30, 100, 500] do
    test_roots_d(x^10 - x + 1, p, p div 50 + 10);
    test_roots_d((x - 1)^20 - 3*x + 7, p, p div 50 + 20);
end for;

"\nHard 1";
f := x^20 + 88817841970012523233890533447265625*x^19 - x - 
    515377520732011331036461129765621272702107522001;
test_roots(f, 1000, 10.0^-600);
test_roots(f, 2000, 10.0^-2600);
test_roots(f, 5000, 10.0^-1000);

"\nHard 2";
f := x^100 + 8100000000*x^4 + 108000000*x^3 + 540000*x^2 + 1200*x + 1;
test_roots(f, 30, 10.0^-35);
test_roots(f, 100, 10.0^-175);
test_roots(f, 1000, 10.0^-1970);

"\nHard 3";
f := 1 + 10^400*x - 10^801*x^2 + 10^800*x^3;
test_roots(f, 1000, 10.0^-390);

"\nHard 4";
f :=
1447159821293962629829472327490910180410850344693136923704504407555506649544646\
    160841115922412123443304006655456466178561632559267297111148504382482114919\
    622676429941067752356927971569586402342890295000533961929951486746911856881\
    279433325284709157076153081614831585919684523810594983832991390297070764822\
    137085463939913215638171038818979586612140076840223008687758150554303241139\
    164828079136061210404551794433103856049765984711719318179457407292594938523\
    9270905669*x^6 + 3555447888840354544899205453451105930789404039206161481791\
    980412858872928336994395977574409825566877810359133233335289358165050159880\
    011050521579161190432557482851541407423212861473491100378289087162779985263\
    942535134744925344511127311771436296829378182250952760045508638678527693194\
    855202148665756346197257218394972115220587469588573599851957951453339682364\
    776854783084585472351239152551984335075500574019382825863974429598970611253\
    8203257883772168713885093560532*x^5 + 3639660683479408406879713244915867648\
    020137348564661198287089615995208523185569210070969706183628894857300526094\
    405746459956668478807445191208470075549541692669420370403977270098732529895\
    764401634154713047776780709347001935936596434485223909531424344195424975886\
    158642431608340775080756176510796138499931680948195158123189907443752186592\
    864358731412987940903705236415986728623273056438338466240062757049447157568\
    4365429679756090211544340394067308600340439146279206*x^4 + 
    198712965642690271406427916195630917475652060179617303281129748213729409734\
    584939706287055122665723321239875802785062548393934760422933757975074315699\
    863251109533427521827611254154264491994849639928391652366344165904250265329\
    390724521544623699595308967055078049258070670178195572132597931077231441488\
    661480814526451304318397596069607634506801348989014035311641970918116195738\
    124499032479740113324810358072270293362939508235492080473368018837152216714\
    22531937267472*x^3 + 610258783950161239925297455306535291717483623104142918\
    500651155986224985992332170238992738759644787257085112437025620879906054754\
    097481697270633554918754550893873552260160863746090688726277270904523789728\
    881941092052469582214648337462692981052773655593871777046730848321660246966\
    790530522928764030373692863627488845280329683550065421700811003446189318434\
    590105119035660891309056299974083546072467329823221609814368585366170550016\
    6511374646838096425120817536356348*x^2 + 
    999540973574860501689524984194009563763865259950810238075271764099338076899\
    733951018175090270704754564053693593621852148583403721106476721161693636873\
    804769010799669977066810496263837319414027328167930855605030760582372458694\
    895799908194841960193685192540665315417507942813342897599606204171844528790\
    699098912744921082598578658307013393649163209877190272467880167353048300729\
    896583465239707534289457447387351778925670676749268739793485924687740473562\
    559292005712*x + 6821437779969295642957054101664562497711113738012990375384\
    905131498797624961232647345155330028356900535603774772521694591714803083159\
    659011641106006386666642402852749144402946863816695274935070228193119552092\
    354890445232006438032797527469600991955302359177446044813132641534921053689\
    609512467756713986046136841413051300515451358020548135481147988850358578203\
    622937422906065907054736329662410621572306695140042486522947571524912735377\
    5826033549976552531906591880;
test_roots(f, 1000, 10.0^-1075);
test_roots(f, 2000, 10.0^-3070);

"\nHard 5";
f:=
x^16 + 9268764703216501997711433743732834304*x^14 + 
    49536220229629204991817678196934509086967865409432434073993905577132032*x^1\
    2 + 72922631295122082058756234650610293267373017742406973737803680602390734\
    40387961227693923601532814622720*x^10 + 
    125484924281249317348093758575552358989348903469830426335925998503208254404\
    8115564100810589991428257049411269925398109861146527793152*x^8 + 
    984268936232692732871076106766017577085228603142394260915423283801419700796\
    1188970937832931688851756620731467482071186232712399854784067888218112*x^6 +
    190484752083785739126476830812441674431874006303257778268073634051466713545\
    011676417327865192067273465774913658815753667150459871719581573235965680199\
    0344704*x^4 + 1208287732735411872323278143234844118165522970693028313936060\
    038240816087379190459552500247664140442504193335606248665614091462172033347\
    87719211729138221324435456*x^2 + 275711754813631278195681561790373310594949\
    801871736545546966204282931369247028452116829544644928723326140075230182168\
    82964157354280970930861497194378083660988416;
test_roots(f, 500, 10.0^-400);
test_roots(f, 1000, 10.0^-1400);


"\nInexact 1";
f:= x^22 + 0.3p500*x^5 - 1.3p500;
test_roots(f, 500, 10.0^-990);


// Oct 20
f :=
Polynomial(\[10233136252724620393145211405736202043362958530505312354556226261218718482967,
-10563513373969664047754788664360767147556721684744735173133740926793464465832,
4089208774057116815769408823241281869277068475958213280968603611133695621900,
-703538167688737670671352061734108645786769069715248682432595468563310235728,
45390744953064436643934471330928888629655433673347917133952855236857207772]);
R1 := Roots(f, ComplexField());
R2 := Roots(f, ComplexField(500));

assert #R1 eq 4 and #R2 eq 4;
&and[Abs(R1[i, 1] - R2[i, 1]) le 10^-28: i in [1..#R1]];



