cpxrn.red 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. module cpxrn; % *** Support for Complex Rationals.
  2. % Authors: Anthony C. Hearn and Stanley L. Kameny.
  3. % Copyright (c) 1989 The RAND Corporation. All rights reserved.
  4. Comment this module defines a complex rational as:
  5. (<tag>. (<structure> . <structure>>).
  6. The <tag> is '!:crn!: and the <structure> is (n . d) where n and d are
  7. integers;
  8. fluid '(!:prec!:);
  9. global '(bfone!* epsqrt!*);
  10. fluid '(dmode!* !*bfspace !*numval);
  11. switch bfspace,numval; !*bfspace := !*numval := t;
  12. global '(domainlist!*);
  13. domainlist!* := union('(!:crn!:),domainlist!*);
  14. fluid '(!*complex!-rational);
  15. put('complex!-rational,'tag,'!:crn!:);
  16. put('!:crn!:,'dname,'complex!-rational);
  17. flag('(!:crn!:),'field);
  18. put('!:crn!:,'i2d,'i2crn!*);
  19. put('!:crn!:,'plus,'crn!:plus);
  20. put('!:crn!:,'times,'crn!:times);
  21. put('!:crn!:,'difference,'crn!:differ);
  22. put('!:crn!:,'quotient,'crn!:quotient);
  23. put('!:crn!:,'zerop,'crn!:zerop);
  24. put('!:crn!:,'onep,'crn!:onep);
  25. put('!:crn!:,'prepfn,'crn!:prep);
  26. put('!:crn!:,'prifn,'crn!:prin);
  27. put('!:crn!:,'minus,'crn!:minus);
  28. put('!:crn!:,'factorfn,'crn!:factor);
  29. put('!:crn!:,'rationalizefn,'girationalize!:);
  30. put('!:crn!:,'!:rn!:,'!*crn2rn);
  31. put('!:rn!:,'!:crn!:,'!*rn2crn);
  32. put('!:rd!:,'!:crn!:,'!*rd2crn);
  33. put('!:crn!:,'!:rd!:,'!*crn2rd);
  34. put('!:gi!:,'!:crn!:,'!*gi2crn);
  35. put('!:crn!:,'cmpxfn,'mkcrn);
  36. put('!:crn!:,'ivalue,'mkdcrn);
  37. put('!:crn!:,'intequivfn,'crnequiv);
  38. put('!:crn!:,'realtype,'!:rn!:);
  39. put('!:rn!:,'cmpxtype,'!:crn!:);
  40. put('!:crn!:,'minusp,'crn!:minusp);
  41. symbolic procedure crn!:minusp u; caddr u=0 and minusp caadr u;
  42. symbolic procedure mkcrn(u,v); '!:crn!: . u . v;
  43. symbolic smacro procedure crntag x; '!:crn!: . x;
  44. symbolic smacro procedure rntag x; '!:rn!: . x;
  45. symbolic smacro procedure crnrl x; cadr x;
  46. symbolic smacro procedure crnim x; cddr x;
  47. symbolic procedure crn!:simp u; (crntag u) ./ 1;
  48. put('!:crn!:,'simpfn,'crn!:simp);
  49. symbolic procedure mkdcrn u;
  50. ('!:crn!: . ((0 . 1) . (1 . 1))) ./ 1;
  51. symbolic procedure i2crn!* u; mkcrn(u . 1,0 . 1);
  52. %converts integer U to tagged crn form.
  53. symbolic procedure !*crn2rn n;
  54. % Converts a crn number n into a rational if possible.
  55. if not(car crnim n=0) then cr2rderr() else '!:rn!: . crnrl n;
  56. symbolic procedure !*rn2crn u; mkcrn(cdr u,0 . 1);
  57. % Converts the (tagged) rational u/v into a (tagged) crn.
  58. symbolic procedure !*crn2rd n;
  59. if not(car crnim n=0) then cr2rderr() else
  60. mkround chkrn!* r2bf crnrl n;
  61. symbolic procedure !*rd2crn u; mkcrn(realrat x,0 . 1) where x=round!* u;
  62. symbolic procedure !*gi2crn u; mkcrn((cadr u) . 1,(cddr u) . 1);
  63. symbolic procedure crn!:plus(u,v);
  64. mkcrn(cdr rnplus!:(rntag crnrl u,rntag crnrl v),
  65. cdr rnplus!:(rntag crnim u,rntag crnim v));
  66. symbolic procedure crn!:differ(u,v);
  67. mkcrn(cdr rndifference!:(rntag crnrl u,rntag crnrl v),
  68. cdr rndifference!:(rntag crnim u,rntag crnim v));
  69. symbolic procedure crn!:times(u,v);
  70. mkcrn(cdr rndifference!:(rntimes!:(ru,rv),rntimes!:(iu,iv)),
  71. cdr rnplus!:(rntimes!:(ru,iv),rntimes!:(rv,iu)))
  72. where ru=rntag crnrl u,iu=rntag crnim u,
  73. rv=rntag crnrl v,iv=rntag crnim v;
  74. symbolic procedure crn!:quotient(u,v);
  75. <<v := rnplus!:(rntimes!:(rv,rv),rntimes!:(iv,iv));
  76. mkcrn(cdr rnquotient!:(rnplus!:(rntimes!:(ru,rv),rntimes!:(iu,iv)),v),
  77. cdr rnquotient!:(rndifference!:(rntimes!:(iu,rv),rntimes!:(ru,iv)),v))>>
  78. where ru=rntag crnrl u,iu=rntag crnim u,
  79. rv=rntag crnrl v,iv=rntag crnim v;
  80. symbolic procedure crn!:minus u;
  81. mkcrn((-car ru) . cdr ru,(-car iu) . cdr iu)
  82. where ru=crnrl u,iu=crnim u;
  83. symbolic procedure crn!:zerop u; car crnrl u=0 and car crnim u=0;
  84. symbolic procedure crn!:onep u; car crnim u=0 and crnrl u='(1 . 1);
  85. symbolic procedure crn!:prep u;
  86. crnprep1((rntag crnrl u) . rntag crnim u);
  87. symbolic procedure crn!:factor u;
  88. (begin scalar m,n,p,x,y;
  89. setdmode('rational,nil) where !*msg = nil;
  90. x := subf(u,nil);
  91. y := fctrf numr x;
  92. n := car y;
  93. setdmode('rational,t) where !*msg = nil;
  94. y := for each j in cdr y collect
  95. <<p := numr subf(car j,nil);
  96. n := multd(n,m := exptf(lnc ckrn p,cdr j));
  97. quotfd(p,m) . cdr j>>;
  98. return int!-equiv!-chk quotfd(n,denr x) . y
  99. end) where dmode!*=dmode!*;
  100. symbolic procedure crnprimp u;
  101. if rnonep!: u then 'i
  102. else if rnonep!: rnminus!: u then list('minus,'i)
  103. else list('times,rnprep!: u,'i);
  104. symbolic procedure crnprep1 u;
  105. if rnzerop!: cdr u then rnprep!: car u
  106. else if rnzerop!: car u then crnprimp cdr u
  107. else if rnminusp!: cdr u
  108. then list('difference,rnprep!: car u,crnprimp rnminus!: cdr u)
  109. else list('plus,rnprep!: car u,crnprimp cdr u);
  110. symbolic procedure crn!:prin u;
  111. (if atom v or car v eq 'times or car v memq domainlist!*
  112. then maprin v
  113. else <<prin2!* "("; maprin v; prin2!* ")">>) where v=crn!:prep u;
  114. symbolic procedure crnequiv u;
  115. % Returns an equivalent integer if possible.
  116. if cadr(u := cdr u) = 0 and cdar u = 1 then caar u else nil;
  117. initdmode 'complex!-rational;
  118. endmodule;
  119. end;