coddom.red 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. module coddom;
  2. % ------------------------------------------------------------------- ;
  3. % Copyright : J.A. van Hulzen, Twente University, Dept. of Computer ;
  4. % Science, P.O.Box 217, 7500 AE Enschede, the Netherlands.;
  5. % Author : W.N. Borst. ;
  6. % ------------------------------------------------------------------- ;
  7. symbolic$
  8. fluid '(!:prec!:);
  9. fluid '(pline!* posn!* orig!* ycoord!* ymax!* ymin!*);
  10. symbolic procedure zeropp u;
  11. % Returns T if u equals 0, regardless of u being
  12. % an integer or an floating-point number.
  13. if atom u then zerop u
  14. else if car u eq '!:rd!: then rd!:zerop u
  15. else nil$
  16. symbolic procedure constp c;
  17. % Returns T iff c is a number, NIL otherwise
  18. numberp(c) or (pairp(c) and memq(car c, domainlist!*))$
  19. symbolic procedure integerp i;
  20. % Returns T iff i is an integer, NIL otherwise
  21. numberp(i) and not floatp(i)$
  22. symbolic procedure floatprop f;
  23. % Returns T iff f is a (domain mode) float, NIL otherwise
  24. floatp(f) or eqcar(f,'!:rd!:)$
  25. symbolic procedure domprop d;
  26. % Returns T iff d is a domain element, NIL otherwise
  27. pairp(d) and memq(car d, domainlist!*);
  28. symbolic procedure doublep d;
  29. % Returns T iff d is an arbitrary precision rounded number, else NIL
  30. eqcar(d,'!:rd!:) and pairp(cdr d);
  31. symbolic procedure nil2zero u;
  32. % Conversion NIL -> 0 needed for domain mode operations
  33. if null(u) then 0 else u;
  34. symbolic procedure zero2nil u;
  35. % Conversion 0 -> NIL needed for domain mode operations
  36. if !:zerop(u) then nil else u;
  37. symbolic procedure dm!-plus(u,v);
  38. nil2zero(!:plus(zero2nil u, zero2nil v));
  39. symbolic procedure dm!-difference(u,v);
  40. nil2zero(!:difference(zero2nil u, v));
  41. symbolic procedure dm!-minus(u);
  42. nil2zero(!:minus(u));
  43. symbolic procedure dm!-abs(u);
  44. if !:minusp(u) then dm!-minus(u) else u;
  45. symbolic procedure dm!-min(u,v);
  46. % Domain mode minimum
  47. if dm!-gt(u,v) then v else u;
  48. symbolic procedure dm!-max(u,v);
  49. % Domain mode maximum
  50. if dm!-gt(u,v) then u else v;
  51. symbolic procedure dm!-times(u,v);
  52. nil2zero(!:times(zero2nil u,zero2nil v));
  53. symbolic procedure dm!-mkfloat(u);
  54. % Use consistent and version independent trafo:
  55. if integerp u then
  56. %'!:rd!: . (u + 0.0)
  57. %i2rd!* u
  58. apply1(get('!:rd!:,'i2d),u)
  59. else u;
  60. symbolic procedure dm!-quotient(u,v);
  61. % ---
  62. % Domain mode quotient
  63. % Always performs a floating point division and returns integers
  64. % when possible
  65. % ---
  66. begin scalar noequiv;
  67. noequiv:=!*noequiv;
  68. !*noequiv:=nil; % for integer results in productscheme
  69. return nil2zero(!:quotient(dm!-mkfloat u,dm!-mkfloat v));
  70. !*noequiv:=noequiv;
  71. end;
  72. symbolic procedure dm!-expt(u,n);
  73. nil2zero(!:expt(zero2nil u,n));
  74. symbolic procedure dm!-gt(u,v);
  75. % Domain mode greater than
  76. !:minusp(dm!-difference(v,u));
  77. symbolic procedure dm!-eq(u,v);
  78. % Domain mode equal to
  79. !:zerop(dm!-difference(u,v));
  80. symbolic procedure dm!-lt(u,v);
  81. % Domain mode less than
  82. !:minusp dm!-difference(u,v);
  83. symbolic procedure dm!-print(p);
  84. % ---
  85. % Domain mode PRIN2. This is an adapted version of mathprint.
  86. % It is used for printing floats in the data structures
  87. % (part 1 of CODPRI)
  88. % ---
  89. begin
  90. terpri!* nil;
  91. maprint(p,0);
  92. pline!* := reverse pline!*;
  93. scprint(pline!*, ymax!*);
  94. pline!* := nil;
  95. posn!* := orig!*;
  96. ycoord!* := ymax!* := ymin!* := 0;
  97. end;
  98. symbolic procedure rd!:zerop!: u;
  99. if atom cdr u then
  100. ft!:zerop cdr u
  101. else
  102. bfzerop!: round!* u;
  103. %-----------------------------------
  104. % R3.5 seems to have machine-dependent precision algorithms.
  105. % So we comment this out :
  106. %
  107. %symbolic procedure bfzerop!: u;
  108. %% A new bigfloat zerop test which respects the precision setting
  109. %begin scalar x;
  110. % return
  111. % << x:=cadr(u) * 10^(cddr(u) + !:prec!:);
  112. % ((x>-50) and (x<50))
  113. % >>
  114. %end;
  115. symbolic procedure ft!:zerop u;
  116. begin scalar x;
  117. return
  118. << x:=u * 10^!:prec!:;
  119. (x>-50 and x<50)
  120. >>
  121. end;
  122. symbolic procedure ftintequiv u;
  123. begin scalar x;
  124. return
  125. if ft!:zerop(u-(x := fix u)) then x else nil
  126. end;
  127. symbolic procedure dm!-fixp u;
  128. % u = (m . e), meaning m*10^e.
  129. % Returned : fix(u) if u is interpretable as an integer,
  130. % nil otherwise.
  131. % JB 14/4/94
  132. begin scalar r,fp;
  133. r:=reverse explode car u;
  134. fp:='t;
  135. if (cdr u) >= 0
  136. then for i:=1:(cdr u) do r:='!0 . r
  137. else if (fp:=(length(r) > -(cdr u)))
  138. then for i:=1:-cdr(u) do <<fp:=fp and eq(car r,'!0);
  139. r:=cdr r>>
  140. else r:= list '!0;
  141. return if fp then compress reverse r
  142. else nil;
  143. end;
  144. symbolic procedure bfintequiv u;
  145. % We need to be sure we work with radix 10.
  146. % This is guaranteed by `internal2decimal'.
  147. % We need `dm!-fixp' to avoid entering an endless loop.
  148. % JB 14/4/94
  149. begin scalar i;
  150. i:=dm!-fixp internal2decimal(u,!:prec!:);
  151. return
  152. if i then i else u
  153. end;
  154. symbolic procedure rdintequiv u;
  155. if atom cdr u then
  156. ftintequiv cdr u
  157. else
  158. bfintequiv u;
  159. put('!:rd!:,'intequivfn,'rdintequiv);
  160. % complex mode . Is momentarliy superfluous ??
  161. symbolic expr procedure complexp v;
  162. ('complex member getdec(car v))
  163. or
  164. (!*complex and not(freeof(cdr v,'i)));
  165. symbolic procedure myprepsq u;
  166. if null numr u then 0 else sqform(u,function myprepf);
  167. symbolic procedure myprepf u;
  168. (if null x then 0 else replus x) where x=myprepf1(u,nil);
  169. symbolic procedure myprepf1(u,v);
  170. if null u then nil
  171. else if domainp u then list retimes(u . exchk v)
  172. else nconc!*(myprepf1(lc u,if mvar u eq 'k!* then v
  173. else lpow u . v),
  174. myprepf1(red u,v));
  175. symbolic procedure cireval u;
  176. % (plus a (times b i)) -> (!:cr!: !:crn!: !:gi!:)
  177. begin
  178. scalar ocmplx, res;
  179. ocmplx:=!*complex;!*complex:='t;
  180. res :=if freeof(u,'i)
  181. then u
  182. else myprepsq cadr aeval ireval u;
  183. !*complex:=ocmplx;
  184. return res;
  185. end$
  186. symbolic procedure remcomplex u;
  187. % (!:cr!: !:crn!: !:gi!:) -> (plus a (times b i))
  188. if atom u
  189. then u
  190. else if member(car u,'(!:cr!: !:crn!: !:gi!:))
  191. then if eqcar(u,'!:gi!:)
  192. then list('plus,cadr u,list('times,cddr u,'i))
  193. else prepsq cr!:simp u
  194. else if not(constp u) % Could be other domain-notation.
  195. % JB 18/3/94.
  196. then (car u)
  197. . foreach el in cdr u collect remcomplex el
  198. else u;
  199. endmodule;
  200. end;