home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / library / dos / wct / math.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1992-01-01  |  7.5 KB  |  333 lines

  1. unit math;
  2.  
  3. { Written by William C. Thompson - wct@po.cwru.edu }
  4.  
  5. { This unit was written to perform several basic mathematical calculations }
  6. { This unit automatically generates a random seed }
  7.  
  8. interface
  9.  
  10. const e=2.7182818284905;
  11.  
  12. function adjust(a:real):real;
  13. procedure quad(a,b,c: real; var x1,x2: real; var im:real);
  14. function relerror(observed,actual: real):real;
  15. function pow(a,b:real):real;
  16. function sign(r:real):integer;
  17. function rmax(r,s:real):real;
  18. function rmin(r,s:real):real;
  19. function imax(m,n:integer):integer;
  20. function imin(m,n: integer):integer;
  21. function log(x,base: real): real;
  22. function tan(a:real):real;
  23. function arcsin(x:real):real;
  24. function arccos(x:real):real;
  25. function arctan2(y,x:real):real;
  26. function degtorad(d:real):real;
  27. function radtodeg(r:real):real;
  28. function gcd(m,n:longint):word;
  29. function lcm(m,n:integer):integer;
  30. function prime(n:longint):boolean;
  31. function rnd(a,b:real):real;
  32. function rnd2(a,b:real):real;
  33. function gaussian(mu,sigma:real):real;
  34. function distance(x1,y1,x2,y2:real):real;
  35. function findline(x1,y1,x2,y2: real; var a,b:real):boolean;
  36. function hero(a,b,c:real):real;
  37. function factorial(n:word):extended;
  38. function stirling(x:real):extended;
  39. function combination(n,r:word):word;
  40. function permutation(n,r:word):word;
  41.  
  42. implementation
  43.  
  44. function adjust(a:real):real;
  45. { Adjusts angle to fit into (-pi,pi] }
  46. begin
  47.   repeat
  48.     if a<=-pi then a:=a+2*pi;
  49.     if a>pi then a:=a-2*pi
  50.   until (a>-pi) and (a<=pi);
  51.   adjust:=a
  52. end;
  53.  
  54. procedure quad(a,b,c:real; var x1,x2: real; var im:real);
  55. { Solves any quadratic equation.  If im=0, x1 and x2 are
  56.   two real solutions.  If im<>0, x1 and x2 are real parts
  57.   of two solutions and im is imaginary part.  The two
  58.   solutions would be x1 + im I and x2 - im I }
  59. var d,q: real;
  60. begin
  61.   im:=0.0;
  62.   if a=0 then begin
  63.     x1:=-c/b;
  64.     x2:=-c/b
  65.     end
  66.   else begin
  67.     b:=b/a;
  68.     c:=c/a;
  69.     a:=1;
  70.     d:=b*b-4*c;
  71.     q:=-b/2;
  72.     if d<0 then begin
  73.       x1:=q;
  74.       x2:=q;
  75.       im:=sqrt(-d)/2
  76.       end
  77.     else begin
  78.       if b<0 then q:=q+sqrt(d)/2
  79.       else q:=q-sqrt(d)/2;
  80.       x1:=q;
  81.       if q=0 then x2:=-b
  82.       else x2:=c/q;
  83.       if x2<x1 then begin
  84.         d:=x1;
  85.         x1:=x2;
  86.         x2:=d
  87.         end
  88.       end   { d>=0 }
  89.     end  { a<>0 }
  90. end;
  91.  
  92. function relerror(observed, actual: real):real;
  93. { Relative error }
  94. begin
  95.   if actual=0.0 then relerror:=abs(observed)
  96.   else relerror:=abs(observed/actual-1)
  97. end;
  98.  
  99. function pow(a,b: real):real;
  100. { Computes a^b }
  101. begin
  102.   if a=0 then
  103.     if b=0 then pow:=1                           { 0^0 = 1 }
  104.     else if b<0 then pow:=exp(b*ln(a))           { force error }
  105.     else pow:=0                                  { 0^x = 0 }
  106.   else if a<0 then
  107.     if abs(b)<1e-10 then pow:=1
  108.     else if relerror(b,round(b))<1e-8 then
  109.       pow:=(1-2*ord(odd(round(b))))*exp(b*ln(abs(a)))
  110.     else if (relerror(1/b,round(1/b))<1e-8) and odd(round(1/b)) then
  111.       pow:=-exp(b*ln(abs(a)))
  112.     else pow:=exp(b*ln(a))                       { force error }
  113.   else pow:=exp(b*ln(a))
  114. end;
  115.  
  116. function sign(r:real):integer;
  117. begin
  118.   if r<0 then sign:=-1
  119.   else if r>0 then sign:=1
  120.   else sign:=0
  121. end;
  122.  
  123. function rmax(r,s:real):real;
  124. begin  if s>=r then rmax:=s else rmax:=r  end;
  125.  
  126. function rmin(r,s:real):real;
  127. begin  if s<=r then rmin:=s else rmin:=r  end;
  128.  
  129. function imax(m,n:integer):integer;
  130. begin  if m>=n then imax:=m else imax:=n  end;
  131.  
  132. function imin(m,n:integer):integer;
  133. begin  if m<=n then imin:=m else imin:=n  end;
  134.  
  135. function log(x,base:real):real;
  136. { Computes log of x base base }
  137. begin
  138.   if (base=0) and (x=0) then log:=1
  139.   else if (base=0) and (x=1) then log:=0
  140.   else log:=ln(x)/ln(base)
  141. end;
  142.  
  143. function tan(a:real):real;
  144. begin
  145.   a:=adjust(a);
  146.   if abs(a-pi/2)<1e-10 then tan:=9.99e+37
  147.   else if abs(a-3*pi/2)<1e-10 then tan:=-9.99e+37
  148.   else tan:=sin(a)/cos(a)
  149. end;
  150.  
  151. function arcsin(x:real):real;
  152. begin
  153.   if x<0 then arcsin:=-arcsin(-x)
  154.   else
  155.     if x=1 then arcsin:=pi/2
  156.     else arcsin:=arctan(x/sqrt(1-x*x))
  157. end;
  158.  
  159. function arccos(x:real):real;
  160. begin
  161.   if x<0 then arccos:=pi-arccos(-x)
  162.   else
  163.     if x=0 then arccos:=pi/2
  164.     else arccos:=arctan(sqrt(1-x*x)/x)
  165. end;
  166.  
  167. function arctan2(y,x:real):real;
  168. { Computes angle of point (x,y) }
  169. var at2:real;
  170. begin
  171.   if x=0 then
  172.     if y>=0 then arctan2:=pi/2
  173.     else arctan2:=-pi/2
  174.   else begin
  175.     at2:=arctan(abs(y/x));
  176.     if x>0 then
  177.       if y>0 then arctan2:=at2
  178.       else arctan2:=adjust(-at2)
  179.     else
  180.       if y>0 then arctan2:=adjust(pi-at2)
  181.       else arctan2:=adjust(-pi+at2);
  182.     end
  183. end;
  184.  
  185. function degtorad(d:real):real;
  186. { Convert degrees to radians }
  187. begin
  188.   degtorad:=d*pi/180
  189. end;
  190.  
  191. function radtodeg(r:real):real;
  192. { Convert radians to degrees }
  193. begin
  194.   radtodeg:=r*180/pi
  195. end;
  196.  
  197. function gcd(m,n:longint):word;
  198. { Greatest Common Divisor }
  199. var k,l,r:integer;
  200. begin
  201.   m:=abs(m);  n:=abs(n);
  202.   if m=0 then gcd:=n else begin
  203.     k:=m;
  204.     l:=n;
  205.     while n<>0 do begin
  206.       r:=m mod n;
  207.       m:=n;
  208.       n:=r
  209.       end;
  210.     gcd:=m
  211.     end
  212. end;
  213.  
  214. function lcm(m,n:integer):integer;
  215. { Least common multiple }
  216. begin
  217.   if (m=0) and (n=0) then lcm:=0
  218.   else lcm:=abs(round((m*1.0)*n) div gcd(m,n))
  219. end;
  220.  
  221. function prime(n:longint):boolean;
  222. { Tests a number for primeness }
  223. var
  224.   p: boolean;
  225.   i, limit: word;
  226. begin
  227.   n:=abs(n);
  228.   if n in [0..1] then prime:=false
  229.   else if n in [2..3] then prime:=true
  230.   else begin
  231.     p:=false;
  232.     i:=2;
  233.     limit:=round(sqrt(n));
  234.     while (i<=limit) and not p do begin
  235.       if (n mod i=0) then p:=true;
  236.       i:=i+1
  237.       end;
  238.     prime:=not p
  239.     end
  240. end;
  241.  
  242. function rnd(a,b:real):real;
  243. { divides interval from a to b, inclusive, into 65535 values and
  244.   chooses one }
  245. begin
  246.   rnd:=a+random(65535)/65534*(b-a)
  247. end;
  248.  
  249. function rnd2(a,b: real):real;
  250. { Similar to rnd, but MANY more divisions (over 4 million) }
  251. begin
  252.   rnd2:=a+(65535.0*random(65535)+random(65535))/(sqr(65535.0)-1)*(b-a)
  253. end;
  254.  
  255. function gaussian(mu,sigma:real):real;
  256. { Produces a Gaussian distributed random variable with mean mu
  257.   and standard deviation sigma }
  258. var
  259.   r,v1,v2: real;
  260. begin
  261.   repeat
  262.     v1:=rnd(-1,1);
  263.     v2:=rnd(-1,1);
  264.     r:=sqr(v1)+sqr(v2)
  265.   until (r<1) and (r>0);
  266.   gaussian:=v1*sqrt(-2*ln(r)/r)*sigma+mu
  267. end;
  268.  
  269. function distance(x1,y1,x2,y2:real):real;
  270. begin
  271.   distance:=sqrt(sqr(x1-x2)+sqr(y1-y2))
  272. end;
  273.  
  274. function findline(x1,y1,x2,y2: real; var a,b:real):boolean;
  275. { Finds equation for line y=ax+b between (x1,y1) and (x2,y2) }
  276. begin
  277.   if x2=x1 then begin
  278.     findline:=false;
  279.     exit
  280.     end;
  281.   findline:=true;
  282.   a:=(y2-y1)/(x2-x1);
  283.   b:=(x2*y1-x1*y2)/(x2-x1);
  284. end;
  285.  
  286. function hero(a,b,c:real):real;
  287. { Finds area of triangle with sides of length s }
  288. var
  289.   s: real;
  290. begin
  291.   s:=a/2+b/2+c/2;
  292.   hero:=sqrt(s*(s-a)*(s-b)*(s-c));
  293. end;
  294.  
  295. function factorial(n:word):extended;
  296. { computes factorial }
  297. var
  298.   i: word;
  299.   f: extended;
  300. begin
  301.   f:=1;
  302.   for i:=1 to n do f:=f*i;
  303.   factorial:=f
  304. end;
  305.  
  306. function stirling(x:real):extended;
  307. { computes factorial according to Stirling's approximation -
  308.   this may not be correct...  it should be, but ask your math professor }
  309. var
  310.   s: extended;
  311.   i: word;
  312. begin
  313.   s:=1;
  314.   for i:=1 to round(x) do s:=s/e*round(x);
  315.   stirling:=s*sqrt(round(x))*sqrt(2.0*pi);
  316. end;
  317.  
  318. function combination(n,r:word):word;
  319. { computes nCr }
  320. begin
  321.   combination:=round((factorial(n)/factorial(n-r))/factorial(r))
  322. end;
  323.  
  324. function permutation(n,r:word):word;
  325. { computes nPr }
  326. begin
  327.   permutation:=round(factorial(n)/factorial(n-r))
  328. end;
  329.  
  330. begin
  331.   randomize
  332. end.
  333.