home *** CD-ROM | disk | FTP | other *** search
- { Copyright (C) 1988 Adam Fritz, 133 Main St., Afton, NY 13730 }
-
- program MinimumHyperbolicAngle (output) ;
-
- { MinHAng - Compute cosh scaled Bxx for sinh }
- { scaled Bxx and list distinct set bit }
- { counts. }
-
- type
- hexstr = string[9] ;
-
- {~~~~~~~~~~~~~~~~~~~~ count set bits ~~~~~~~~~~~~~~~~~~~~~~}
-
- function nBits ( n : longint ) : integer ;
- var
- iBits : integer ;
- begin
- iBits := 0 ;
- while n <> 0 do begin
- if Odd(n) then
- Inc(iBits) ;
- n := n shr 1
- end ;
- nBits := iBits
- end ;
-
- {~~~~~~~~~~~ convert longint to hex string ~~~~~~~~~~~~~~~~}
-
- procedure itoh ( var sn : hexstr ; n : longint ) ;
- const
- hexchr : array[0..15] of char = ('0','1','2','3','4','5','6','7',
- '8','9','A','B','C','D','E','F') ;
- var
- lsn : hexstr ;
- ih,nh : integer ;
- begin
- lsn := '' ;
- if abs(n) < 65536 then
- nh := 4
- else
- nh := 8 ;
- for ih := 1 to nh do begin
- lsn := hexchr[n and $000F] + lsn ;
- n := n shr 4
- end ;
- sn := '$' + lsn
- end ;
-
- {~~~~~~~~~~~~~~~~~ hyperbolic functions ~~~~~~~~~~~~~~~~~~~}
-
- function sinh ( x : single ) : single ;
- begin
- sinh := (exp(x) - exp(-x)) / 2.0
- end ;
-
- function cosh ( x : single ) : single ;
- begin
- cosh := (exp(x) + exp(-x)) / 2.0
- end ;
-
- function arctanh ( x : single ) : single ;
- var
- z,dz0,dz1 : single ;
- coshz, tanhz : single ;
- n : integer ;
- begin
- if abs(x) < 1.0 then begin
- if abs(x) > 0.5 then
- z := ln((1.0 + Sqrt(2.0*x-1.0))/(1.0-x)) / 2.0
- else
- z := ln(2.0 / (1.0 - abs(x))) / 2.0 ;
- dz1 := 1.0 ;
- n := 0 ;
- repeat
- Inc(n) ;
- dz0 := dz1 ;
- coshz := cosh(z) ;
- tanhz := sinh(z) / coshz ;
- dz1 := (abs(x) - tanhz) / Sqr(coshz) ;
- z := z + dz1 ;
- { writeln (n,' ',dz1,' ',z:10:5) }
- until (abs(dz1) >= abs(dz0)) or (abs(dz1) < 5.0e-7) or (n >= 1000) ;
- if x >= 0 then
- arctanh := abs(z)
- else
- arctanh := -abs(z)
- end
- else begin
- writeln('ERROR: Invalid arctanh argument.') ;
- Halt
- end
- end ;
-
- {~~~~~~~~~~~~~~~~~~~~~ main program ~~~~~~~~~~~~~~~~~~~~~~~}
-
- var
- ib : integer ;
- is : longint ;
- dx,dxd,sinhdx,coshdx : single ;
- r : longint ;
- isinhdx,icoshdx : longint ;
- nisinhdx,nicoshdx,nidx : integer ;
- sisinhdx,sicoshdx : hexstr ;
-
- begin
- { get scale }
- repeat
- write ('Scale: ') ;
- readln (ib)
- until (ib > 0) and (ib < 31) ;
- is := longint(1) shl ib ;
-
- isinhdx := is ;
- r := 0 ;
- repeat
- { sinh and cosh }
- Dec(isinhdx) ;
- sinhdx := isinhdx / is ;
- coshdx := sqrt(1.0 + sqr(sinhdx)) ;
- { cosine scaled Bxx }
- icoshdx := Round(coshdx * is) ;
- { count distinct set bits }
- nisinhdx := nBits(isinhdx) ;
- if nisinhdx > ib div 2 then
- nisinhdx := nisinhdx - ib ;
- nicoshdx := nBits(icoshdx) ;
-
- if nicoshdx > ib div 2 then
- nicoshdx := nicoshdx - ib - 1 ;
- nidx := abs(nisinhdx) + abs(nicoshdx) ;
- { hex strings }
- if nidx < 5 then begin
- itoh(sisinhdx,isinhdx) ;
- itoh(sicoshdx,icoshdx) ;
- dx := arctanh(sinhdx/coshdx) ;
- r := Round(4.0/sqr(dx)) ;
- writeln (output,dx:10:5,' ',r:5,
- ' ',sisinhdx,' ',sicoshdx,
- ' ',nisinhdx:4,' ',nicoshdx:4,' ',nidx:4)
- end
- until (isinhdx < 512) or (r > 2000)
- end.
-
- { Copyright (C) 1988 Adam Fritz, 133 Main St., Afton, NY 13730 }
-