wstrass.red 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. module wstrass;
  2. % Author: James H. Davenport.
  3. fluid '(!*exp
  4. !*gcd
  5. !*mcd
  6. !*structure
  7. !*uncached
  8. !*keepsqrts % Forced SIMP to keep square roots around
  9. !*tra
  10. !*trmin
  11. intvar
  12. listofallsqrts
  13. listofnewsqrts
  14. magiclist
  15. previousbasis
  16. sqrt!-intvar
  17. sqrtflag
  18. sqrts!-in!-integrand
  19. taylorasslist
  20. taylorvariable
  21. thisplace
  22. zlist);
  23. global '(coates!-fdi);
  24. exports simpwstrass,weierstrass!-form;
  25. imports gcdn,sqrtsinplaces,
  26. makeinitialbasis,mkvec,completeplaces,integralbasis,
  27. normalbasis,mksp,multsq,xsubstitutesq,taylorform,taylorevaluate,
  28. coatessolve,checkpoles,substitutesq,removecmsq,printsq,interr,
  29. terpri!*,printplace,finitise,fractional!-degree!-at!-infinity,
  30. !*multsq,fdi!-print,fdi!-upgrade,fdi!-revertsq,simp,newplace,
  31. xsubstitutep,sqrtsinsq,removeduplicates,!*exptf,!*multf,
  32. !*multsq,!*q2f,mapvec,upbv,coates!-lineq,addsq,!*addsq;
  33. symbolic procedure simpwstrass u;
  34. begin
  35. scalar intvar,sqrt!-intvar,taylorvariable,taylorasslist;
  36. scalar listofallsqrts,listofnewsqrts;
  37. scalar sqrtflag,sqrts!-in!-integrand,tt,u;
  38. scalar !*keepsqrts,!*exp,!*gcd,!*mcd,!*structure,!*uncached;
  39. !*keepsqrts:=t; % Else nothing will work
  40. !*exp := !*gcd := !*mcd := !*uncached := t;
  41. !*structure := nil; % Algebraic code certainly wants this off:
  42. % keeping it on inhibits sqrt(z)^2 -> z
  43. tt:=readclock();
  44. sqrtflag:=t;
  45. taylorvariable:=intvar:=car u;
  46. sqrt!-intvar:=mvar !*q2f simpsqrti intvar;
  47. u:=for each v in cdr u
  48. collect int!-simp v;
  49. sqrts!-in!-integrand:=sqrtsinsql(u,intvar);
  50. u:=errorset!*('(weierstrass!-form sqrts!-in!-integrand),t);
  51. if atom u
  52. then return u
  53. else u:=car u;
  54. printc list('time,'taken,readclock()-tt,'milliseconds);
  55. printc "New x value is:";
  56. printsq car u;
  57. u:=cdr u;
  58. printc "New y value is:";
  59. printsq car u;
  60. u:=cdr u;
  61. printc "Related by the equation";
  62. printsq car u;
  63. return car u
  64. end;
  65. put('wstrass,'simpfn,'simpwstrass);
  66. symbolic procedure weierstrass!-form sqrtl;
  67. begin
  68. scalar sqrtl2,u,x2,x1,vect,a,b,c,d,lhs,rhs;
  69. if !*tra or !*trmin then <<
  70. printc "Find Weierstrass form for elliptic curve defined by:";
  71. for each u in sqrtl do
  72. printsq simp u >>;
  73. sqrtl2:=sqrts!-at!-infinity sqrtl;
  74. sqrtl2:=append(car sqrtl2,
  75. for each u in cdr sqrtl2 collect
  76. u.u);
  77. % one of the places lying over infinity
  78. % (after deramification as necessary).
  79. x2:=coates!-wstrass(list sqrtl2,list(-3),intvar);
  80. % Note that we do not multiply by the MULTIPLICITY!-FACTOR
  81. % since we genuinely want a pole of order -3 irrespective
  82. % of any ramification problems.
  83. if !*tra then <<
  84. printc "Function with pole of order 3 (x2) is:";
  85. printsq x2 >>;
  86. x1:=coates!-wstrass(list sqrtl2,list(-2),intvar);
  87. if !*tra then <<
  88. printc "Function with pole of order 2 (x1) is:";
  89. printsq x1 >>;
  90. vect := mkvec list(1 ./ 1,
  91. x1,
  92. x2,
  93. !*multsq(x1,x1),
  94. !*multsq(x2,x2),
  95. !*multsq(x1,!*multsq(x1,x1)),
  96. !*multsq(x1,x2));
  97. u:=!*lcm!*(!*exptf(denr x1,3),!*multf(denr x2,denr x2)) ./ 1;
  98. for i:=0:6 do
  99. putv(vect,i,!*q2f !*multsq(u,getv(vect,i)));
  100. if !*tra then <<
  101. printc "List of seven functions in weierstrass!-form:";
  102. mapvec(vect,function printsf) >>;
  103. vect := wstrass!-lineq vect;
  104. if vect eq 'failed then
  105. interr "Linear equation solving failed in Weierstrass";
  106. % printsq(addsq(getv(vect,0),addsq(!*multsq(getv(vect,1),x1),
  107. % addsq(!*multsq(getv(vect,2),x2),
  108. % addsq(!*multsq(getv(vect,3),!*multsq(x1,x1)),
  109. % addsq(!*multsq(getv(vect,4),!*multsq(x2,x2)),
  110. % addsq(!*multsq(getv(vect,5),exptsq(x1,3)),
  111. % !*multsq(getv(vect,6),
  112. % !*multsq(x1,x2)))))))));
  113. x2:=!*addsq(!*multsq(!*multsq(2 ./ 1,getv(vect,4)),x2),
  114. !*addsq(!*multsq(x1,getv(vect,6)),
  115. getv(vect,2)));
  116. putv(vect,4,!*multsq(-4 ./ 1,getv(vect,4)));
  117. a:=!*multsq(getv(vect,4),getv(vect,5));
  118. b:=!*addsq(!*multsq(getv(vect,6),getv(vect,6)),
  119. !*multsq(getv(vect,3),getv(vect,4)));
  120. c:=!*addsq(!*multsq(2 ./ 1,!*multsq(getv(vect,2),getv(vect,6))),
  121. !*multsq(getv(vect,1),getv(vect,4)));
  122. d:=!*addsq(!*multsq(getv(vect,2),getv(vect,2)),
  123. !*multsq(getv(vect,0),getv(vect,4)));
  124. lhs:=!*multsq(x2,x2);
  125. rhs:=!*addsq(d,!*multsq(x1,
  126. !*addsq(c,!*multsq(x1,
  127. !*addsq(b,!*multsq(x1,a))))));
  128. if lhs neq rhs then <<
  129. printsq lhs;
  130. printsq rhs;
  131. interr "Previous two unequal - consistency failure 1" >>;
  132. u:=!*lcm!*(!*lcm!*(denr a,denr b),!*lcm!*(denr c,denr d));
  133. if u neq 1 then <<
  134. % for now use u**2 whereas we should be using the least
  135. % square greater than u**2 (does it really matter).
  136. x2:=!*multsq(x2,u ./ 1);
  137. u:=!*multf(u,u) ./ 1;
  138. a:=!*multsq(a,u);
  139. b:=!*multsq(b,u);
  140. c:=!*multsq(c,u);
  141. d:=!*multsq(d,u) >>;
  142. if (numr b) and not (quotf(numr b,3)) then <<
  143. % multiply all through by 9 for the hell of it.
  144. x2:=multsq(3 ./ 1,x2);
  145. u:=9 ./ 1;
  146. a:=multsq(a,u);
  147. b:=multsq(b,u);
  148. c:=multsq(c,u);
  149. d:=multsq(d,u) >>;
  150. x2:=!*multsq(x2,a);
  151. x1:=!*multsq(x1,a);
  152. c:=!*multsq(a,c);
  153. d:=!*multsq(!*multsq(a,a),d);
  154. lhs:=!*multsq(x2,x2);
  155. rhs:=!*addsq(d,!*multsq(x1,!*addsq(c,!*multsq(x1,!*addsq(b,x1)))));
  156. if lhs neq rhs then <<
  157. printsq lhs;
  158. printsq rhs;
  159. interr "Previous two unequal - consistency failure 2" >>;
  160. b:=quotf(numr b,3) ./ 1;
  161. x1:=!*addsq(x1,b);
  162. d:=!*addsq(d,!*addsq(multsq(2 ./ 1,!*multsq(b,!*multsq(b,b))),
  163. negsq !*multsq(c,b)));
  164. c:=!*addsq(c,multsq((-3) ./ 1,!*multsq(b,b)) );
  165. % b:=nil ./ 1; % not used again.
  166. if !*tra then <<
  167. printsq x2;
  168. printsq x1;
  169. printc "with coefficients";
  170. printsq c;
  171. printsq d;
  172. rhs:=!*addsq(d,
  173. !*addsq(!*multsq(c,x1),
  174. !*multsq(x1,!*multsq(x1,x1)) ));
  175. lhs:=!*multsq(x2,x2);
  176. if lhs neq rhs then <<
  177. printsq lhs;
  178. printsq rhs;
  179. interr "Previous two unequal - consistency failure 3" >> >>;
  180. return weierstrass!-form1(c,d,x1,x2)
  181. end;
  182. symbolic procedure !*lcm!*(u,v); !*multf(u,quotf(v,gcdf(u,v)));
  183. symbolic procedure weierstrass!-form1(c,d,x1,x2);
  184. begin scalar b,u;
  185. u:=gcdf(numr c,numr d);
  186. % We will reduce by anything whose square divides C
  187. % and whose cube divides D.
  188. if not numberp u then begin
  189. scalar cc,dd;
  190. u:=jsqfree(u,mvar u);
  191. u:=cdr u;
  192. if null u
  193. then return;
  194. % We found no repeated factors.
  195. for each v in u do
  196. for each w in v do
  197. while (cc:=quotf(numr c,multf(w,w))) and
  198. (dd:=quotf(numr d,exptf(w,3)))
  199. do <<
  200. c:=cc ./ 1;
  201. d:=dd ./ 1;
  202. x1:=!*multsq(x1,1 ./ w);
  203. x2:=!*multsq(x2,1 ./ multf(w,simpsqrt2 w)) >>;
  204. u:=gcdn(algint!-numeric!-content numr c,
  205. algint!-numeric!-content numr d)
  206. end;
  207. b:=2;
  208. while not(b*b > u) do begin
  209. scalar nc,nd,uu;
  210. nc:=0;
  211. while cdr(uu:=divide(u,b))=0 do <<
  212. nc:=nc+1;
  213. u:=car uu >>;
  214. if nc < 2
  215. then go to next;
  216. uu:=algint!-numeric!-content numr d;
  217. nd:=0;
  218. while cdr(uu:=divide(uu,b))=0 do <<
  219. nd:=nd+1;
  220. uu:=car uu >>;
  221. if nd < 3
  222. then go to next;
  223. nc:=min(nc/2,nd/3);
  224. % re-normalise by b**nc.
  225. uu:=b**nc;
  226. c:=multsq(c,1 ./ (uu**2));
  227. d:=multsq(d,1 ./ (uu**3));
  228. x1:=multsq(x1,1 ./ uu);
  229. x2:=multsq(x2,1 ./ (uu*b**(nc/2)) );
  230. if not evenp nc
  231. then x2:=!*multsq(x2,!*invsq simpsqrti b);
  232. next:
  233. b:=nextprime(b)
  234. end;
  235. u:=!*kk2q intvar;
  236. u:=!*addsq(!*addsq(d,multsq(c,u)),exptsq(u,3));
  237. if !*tra or !*trmin then <<
  238. printc "Standard form is y**2 = ";
  239. printsq u >>;
  240. return list(x1,x2,simpsqrtsq u)
  241. end;
  242. symbolic procedure sqrts!-at!-infinity sqrtl;
  243. begin
  244. scalar inf,hack,sqrtl2,repeating;
  245. hack:=list list(intvar,'expt,intvar,2);
  246. inf:=list list(intvar,'quotient,1,intvar);
  247. sqrtl2:=list sqrt!-intvar;
  248. while sqrt!-intvar member sqrtl2 do <<
  249. if repeating
  250. then inf:=append(inf,hack);
  251. newplace inf;
  252. sqrtl2:=for each v in sqrtl conc
  253. sqrtsinsq(xsubstitutep(v,inf),intvar);
  254. repeating:=t >>;
  255. sqrtl2:=removeduplicates sqrtl2;
  256. return inf.sqrtl2
  257. end;
  258. symbolic procedure coates!-wstrass(places,mults,x);
  259. begin
  260. scalar thisplace,u,finite!-hack,save,places2,mults2;
  261. if !*tra or !*trmin then <<
  262. princ "Find function with zeros of order:";
  263. printc mults;
  264. if !*tra then
  265. princ " at ";
  266. terpri!*(t);
  267. if !*tra then
  268. mapc(places,function printplace) >>;
  269. % finite!-hack:=placesindiv places;
  270. % FINITE!-HACK is a list of all the substitutors in PLACES;
  271. % u:=removeduplicates sqrtsintree(finite!-hack,x,nil);
  272. % if !*tra then <<
  273. % princ "Sqrts on this curve:";
  274. % terpri!*(t);
  275. % superprint u >>;
  276. % algnos:=removeduplicates for each j in places collect basicplace j;
  277. % if !*tra then <<
  278. % printc "Algebraic numbers where residues occur:";
  279. % superprint algnos >>;
  280. finite!-hack:= finitise(places,mults);
  281. % returns list (places,mults,power of x to remove.
  282. places2:=car finite!-hack;
  283. mults2:=cadr finite!-hack;
  284. finite!-hack:=list(places,mults,caddr finite!-hack);
  285. coates!-fdi:=fractional!-degree!-at!-infinity u;
  286. if coates!-fdi iequal 1
  287. then return !*multsq(wstrassmodule(places2,mults2,x,finite!-hack),
  288. !*p2q mksp(x,caddr finite!-hack));
  289. if !*tra
  290. then fdi!-print();
  291. newplace list(intvar . thisplace,
  292. list(intvar,'expt,intvar,coates!-fdi));
  293. places2 := for each j in places2 collect fdi!-upgrade j;
  294. save:=taylorasslist;
  295. u:=wstrassmodule(places2,
  296. for each u in mults2 collect u*coates!-fdi,
  297. x,finite!-hack);
  298. taylorasslist:=save;
  299. u:=fdi!-revertsq u;
  300. return !*multsq(u,!*p2q mksp(x,caddr finite!-hack))
  301. end;
  302. symbolic procedure wstrassmodule(places,mults,x,finite!-hack);
  303. begin
  304. scalar pzero,mzero,u,v,basis,sqrts,magiclist,mpole,ppole;
  305. % MAGICLIST holds the list of extra unknowns created in JHDSOLVE
  306. % which must be found in CHECKPOLES (calling FINDMAGIC).
  307. sqrts:=sqrtsinplaces places;
  308. if !*tra then <<
  309. princ "Sqrts on this curve:";
  310. superprint sqrts >>;
  311. u:=places;
  312. v:=mults;
  313. while u do <<
  314. if 0<car v
  315. then <<
  316. mzero:=(car v).mzero;
  317. pzero:=(car u).pzero >>
  318. else <<
  319. mpole:=(car v).mpole;
  320. ppole:=(car u).ppole >>;
  321. u:=cdr u;
  322. v:=cdr v >>;
  323. basis:=mkvec makeinitialbasis ppole;
  324. u:=completeplaces(ppole,mpole);
  325. basis:=integralbasis(basis,car u,cdr u,x);
  326. basis:=normalbasis(basis,x,0);
  327. u:=coatessolve(mzero,pzero,basis,force!-pole(basis,finite!-hack));
  328. % This is the list of special constraints needed
  329. % to force certain poles to occur in the answer.
  330. previousbasis:=nil;
  331. if atom u
  332. then return u;
  333. v:= checkpoles(list u,places,mults);
  334. if null v
  335. then return 'failed;
  336. if not magiclist
  337. then return u;
  338. u:=removecmsq substitutesq(u,v);
  339. % Apply the values from FINDMAGIC.
  340. if !*tra or !*trmin then <<
  341. printc "Function is";
  342. printsq u >>;
  343. magiclist:=nil;
  344. if checkpoles(list u,places,mults)
  345. then return u
  346. else interr "Inconsistent checkpoles"
  347. end;
  348. symbolic procedure force!-pole(basis,finite!-hack);
  349. begin
  350. scalar places,mults,u,ans;
  351. places:=car finite!-hack;
  352. mults:=cadr finite!-hack;
  353. finite!-hack:=caddr finite!-hack;
  354. u:=!*p2q mksp(intvar,finite!-hack);
  355. basis:=for each v in basis collect multsq(u,v);
  356. while places do <<
  357. u:=for each v in basis collect
  358. taylorevaluate(taylorform xsubstitutesq(v,car places),
  359. car mults);
  360. mults:=cdr mults;
  361. places:=cdr places;
  362. ans:=u.ans >>;
  363. return ans
  364. end;
  365. symbolic procedure wstrass!-lineq vect;
  366. begin
  367. scalar zlist,powlist,m,rightside,v;
  368. scalar zero,one;
  369. zero:=nil ./ 1;
  370. one:=1 ./ 1;
  371. for i:=0:6 do
  372. zlist:=varsinsf(getv(vect,i),zlist);
  373. zlist:=intvar . findzvars(zlist,nil,intvar,nil);
  374. for i:=0:6 do
  375. putv(vect,i,f2df getv(vect,i));
  376. for i:=0:6 do
  377. for each u in getv(vect,i) do
  378. if not ((tpow u) member powlist)
  379. then powlist:=(tpow u).powlist;
  380. m:=for each u in powlist collect begin
  381. scalar v;
  382. v:=mkvect 6;
  383. for i:=0:6 do
  384. putv(v,i,(lambda u;
  385. if null u
  386. then zero
  387. else tc u)
  388. assoc(u,getv(vect,i)));
  389. return v
  390. end;
  391. v:=mkvect 6;
  392. for i:=0:6 do
  393. putv(v,i,zero);
  394. putv(v,4,one);
  395. % we know that coefficient e is non-zero.
  396. m:=mkvec (v.m);
  397. v:=upbv m;
  398. rightside:=mkvect v;
  399. putv(rightside,0,one);
  400. for i:=1:v do
  401. putv(rightside,i,zero);
  402. return coates!-lineq(m,rightside)
  403. end;
  404. % This is same as NUMERIC!-CONTENT in the EZGCD module, but is included
  405. % here so that that module doesn't need to be loaded.
  406. symbolic procedure algint!-numeric!-content form;
  407. %Find numeric content of non-zero polynomial.
  408. if domainp form then abs form
  409. else if null red form then algint!-numeric!-content lc form
  410. else begin
  411. scalar g1;
  412. g1 := algint!-numeric!-content lc form;
  413. if not (g1=1)
  414. then g1 := gcddd(g1,algint!-numeric!-content red form);
  415. return g1
  416. end;
  417. endmodule;
  418. end;