sqfrnorm.red 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. module sqfrnorm;
  2. % Author: James H. Davenport.
  3. fluid '(!*pvar listofallsqrts);
  4. global '(modevalcount);
  5. modevalcount:=1;
  6. exports sqfr!-norm2,res!-sqrt;
  7. %symbolic procedure resultant(u,v);
  8. %begin
  9. % scalar maxdeg,zeroes,ldegu,ldegv,m;
  10. % % we can have gone makemainvar on u and v;
  11. % ldegu:=ldeg u;
  12. % ldegv:=ldeg v;
  13. % maxdeg:=isub1 max2(ldegu,ldegv);
  14. % zeroes:=nlist(nil,maxdeg);
  15. % u:=remake(u,mvar u,ldegu);
  16. % v:=remake(v,mvar v,ldegv);
  17. % m:=nil;
  18. % ldegu:=isub1 ldegu;
  19. % ldegv:=isub1 ldegv;
  20. % for i:=0 step 1 until ldegv do
  21. % m:=append(ncdr(zeroes,maxdeg-ldegv+i),
  22. % append(u,ncdr(zeroes,maxdeg-i))).m;
  23. % for i:=0 step 1 until ldegu do
  24. % m:=append(ncdr(zeroes,maxdeg-ldegu+i),
  25. % append(v,ncdr(zeroes,maxdeg-i))).m;
  26. % return detqf m
  27. % end;
  28. % symbolic procedure ncdr(l,n);
  29. % % we can use small integer arithmetic here.
  30. % if n=0 then l else ncdr(cdr l,isub1 n);
  31. %symbolic procedure remake(u,v,w);
  32. %% remakes u into a list of sf's representing its coefficients;
  33. %if w iequal 0 then list u
  34. % else if (pairp u) and (mvar u eq v) and (ldeg u iequal w)
  35. % then (lc u).remake(red u,v,isub1 w)
  36. % else (nil ).remake( u,v,isub1 w);
  37. %fluid '(n); %needed for the mapcar;
  38. %symbolic procedure detqf u;
  39. % %u is a square matrix standard form.
  40. %% %value is the determinant of u.
  41. %% %algorithm is expansion by minors of first row/column;
  42. % begin integer n;
  43. % scalar x,y,z;
  44. % if length u neq length car u then rederr "Non square matrix"
  45. % else if null cdr u then return caar u;
  46. % if length u < 3
  47. % then go to noopt;
  48. % % try to remove a row with only one non-zero in it;
  49. % z:=1;
  50. % x:=u;
  51. % loop:
  52. % n:=posnnonnull car x;
  53. % if n eq t
  54. % then return nil;
  55. % % special test for all null;
  56. % if n then <<
  57. % y:=nth(car x,n);
  58. % % next line is equivalent to:
  59. %% onne of n,z is even;
  60. % if evenp (n+z-1)
  61. % then y:=negf y;
  62. % u:=remove(u,z);
  63. % return !*multf(y,detqf remove2 u) >>;
  64. % x:=cdr x;
  65. % z:=z+1;
  66. % if x
  67. % then go to loop;
  68. % noopt:
  69. % x := u;
  70. % n := 1; %number of current row/column;
  71. % z := nil;
  72. % if nonnull car u < nonnullcar u
  73. % then go to row!-expand;
  74. % u:=mapcar(u,function cdr);
  75. % a: if null x then return z;
  76. % y := caar x;
  77. % if null y then go to b
  78. % else if evenp n then y := negf y;
  79. % z := addf(!*multf(y,detqf remove(u,n)),z);
  80. % b: x := cdr x;
  81. % n := iadd1 n;
  82. % go to a;
  83. % row!-expand:
  84. % u:=cdr u;
  85. % x:=car x;
  86. % aa:
  87. % if null x then return z;
  88. % y:=car x;
  89. % if null y
  90. % then go to bb
  91. % else if evenp n then y:=negf y;
  92. % z:=addf(!*multf(y,detqf remove2 u),z);
  93. % bb:
  94. % x:=cdr x;
  95. % n:=iadd1 n;
  96. % go to aa
  97. % end;
  98. %
  99. %
  100. %symbolic procedure remove2 u;
  101. %mapcar(u,function (lambda x;
  102. % remove(x,n)));
  103. %
  104. %unfluid '(n);
  105. %
  106. %symbolic procedure nonnull u;
  107. %if null u
  108. % then 0
  109. % else if null car u
  110. % then nonnull cdr u
  111. % else iadd1 (nonnull cdr u);
  112. %
  113. %
  114. %symbolic procedure nonnullcar u;
  115. %if null u
  116. % then 0
  117. % else if null caar u
  118. % then nonnullcar cdr u
  119. % else iadd1 (nonnullcar cdr u);
  120. %
  121. %
  122. %
  123. %symbolic procedure posnnonnull u;
  124. %% returns t if u has no non-null elements
  125. %% nil if more than one
  126. %% else position of the first;
  127. %begin
  128. % scalar n,x;
  129. % n:=1;
  130. %loop:
  131. % if null u
  132. % then return
  133. % if x
  134. % then x
  135. % else t;
  136. % if car u
  137. % then if x
  138. % then return nil
  139. % else x:=n;
  140. % n:=iadd1 n;
  141. % u:=cdr u;
  142. % go to loop
  143. % end;
  144. symbolic procedure res!-sqrt(u,a);
  145. % Evaluates resultant of u ( as a poly in its mvar) and x**-a.
  146. begin
  147. scalar x,n,v,k,l;
  148. x:=mvar u;
  149. n:=ldeg u;
  150. n:=quotient(n,2);
  151. v:=mkvect n;
  152. putv(v,0,1);
  153. for i:=1:n do
  154. putv(v,i,!*multf(a,getv(v,i-1)));
  155. % now substitute for x**2 in u leaving k*x+l.
  156. k:=l:=nil;
  157. while u do
  158. if mvar u neq x
  159. then <<
  160. l:=addf(l,u);
  161. u:=nil >>
  162. else <<
  163. if evenp ldeg u
  164. then l:=addf(l,!*multf(lc u,getv(v,(ldeg u)/2)))
  165. else k:=addf(k,!*multf(lc u,getv(v,(ldeg u -1)/2)));
  166. u:=red u >>;
  167. % now have k*x+l,x**2-a, giving l*l-a*k*k.
  168. return addf(!*multf(l,l),!*multf(negf a,multf(k,k)))
  169. end;
  170. symbolic procedure sqfr!-norm2 (f,mvarf,a);
  171. begin
  172. scalar u,w,aa,ff,resfn;
  173. resfn:='resultant;
  174. if eqcar(a,'sqrt)
  175. then <<
  176. resfn:='res!-sqrt;
  177. aa:=!*q2f simp argof a >>
  178. else rerror(algint,1,"Norms over transcendental extensions");
  179. f:=pvarsub(f,a,'! gerbil);
  180. w:=nil;
  181. if involvesf(f,'! gerbil) then goto l1;
  182. increase:
  183. w:=addf(w,!*p2f mksp(a,1));
  184. f:=!*q2f algint!-subf(f,list(mvarf . list('plus,mvarf,
  185. list('minus,'! gerbil))));
  186. l1:
  187. u:=apply2(resfn,makemainvar(f,'! gerbil),aa);
  188. ff:=nsqfrp(u,mvarf);
  189. if ff
  190. then go to increase;
  191. f:=!*q2f algint!-subf(f,list('! gerbil.a));
  192. % cannot use pvarsub since want to squash higher powers.
  193. return list(u,w,f)
  194. end;
  195. symbolic procedure nsqfrp(u,v);
  196. begin
  197. scalar w;
  198. w:=modeval(u,v);
  199. if w eq 'failed
  200. then go to normal;
  201. if atom w
  202. then go to normal;
  203. if ldegvar(w,v) neq ldegvar(u,v)
  204. then go to normal;
  205. % printc "Modular image is:";
  206. % printsf w;
  207. w:=gcdf(w,partialdiff(w,v));
  208. % printc "Answer is:";
  209. % printsf w;
  210. if w iequal 1
  211. then return nil;
  212. normal;
  213. w:=gcdf(u,partialdiff(u,v));
  214. if involvesf(w,v)
  215. then return w
  216. else return nil
  217. end;
  218. symbolic procedure ldegvar(u,v);
  219. if atom u
  220. then 0
  221. else if mvar u eq v
  222. then ldeg u
  223. else if ordop(v,mvar u)
  224. then 0
  225. else max2(ldegvar(lc u,v),ldegvar(red u,v));
  226. symbolic procedure modeval(u,v);
  227. if atom u
  228. then u
  229. else if v eq mvar u
  230. then begin
  231. scalar w,x;
  232. w:=modeval(lc u,v);
  233. if w eq 'failed
  234. then return w;
  235. x:=modeval(red u,v);
  236. if x eq 'failed
  237. then return x;
  238. if null w
  239. then return x
  240. else return (lpow u .* w) .+ x
  241. end
  242. else begin
  243. scalar w,x;
  244. x:=mvar u;
  245. if not atom x
  246. then if dependsp(x,v)
  247. then return 'failed;
  248. x:=modevalvar x;
  249. if x eq 'failed
  250. then return x;
  251. w:=modeval(lc u,v);
  252. if w eq 'failed
  253. then return w;
  254. if x
  255. then w:=multf(w,exptf(x,ldeg u));
  256. x:=modeval(red u,v);
  257. if x eq 'failed
  258. then return x;
  259. return addf(w,x)
  260. end;
  261. symbolic procedure modevalvar v;
  262. begin scalar w;
  263. if atom v
  264. then <<if (w := get(v,'modvalue)) then return w;
  265. put(v,'modvalue,modevalcount);
  266. modevalcount := modevalcount+1;
  267. return modevalcount-1>>
  268. else if car v neq 'sqrt
  269. then <<if !*tra then <<princ "Unexpected algebraic:"; print v>>;
  270. error1()>>
  271. else if numberp argof v then return (mksp(v,1) .* 1) .+ nil;
  272. w := modeval(!*q2f simp argof v,!*pvar);
  273. w := assoc(w,listofallsqrts);
  274. % The variable does not matter, since we know it does not depend.
  275. if w then return cdr w else return 'failed
  276. end;
  277. % unglobal '(modevalcount);
  278. endmodule;
  279. end;