home *** CD-ROM | disk | FTP | other *** search
- { Copyright (C) 1988 Adam Fritz, 133 Main St., Afton, NY 13730 }
-
- program MinimumHyperbolicCosine (output) ;
-
- { MinCosh - 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 integer 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 ;
- 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,sinhdx,coshdx : single ;
- r : longint ;
- isinhdx,icoshdx,i2coshdx : longint ;
- ni2coshdx,nidx : integer ;
- sisinhdx,sicoshdx,si2coshdx : hexstr ;
-
- begin
- { get scale }
- repeat
- write ('Scale: ') ;
- readln (ib)
- until (ib > 0) and (ib < 31) ;
- is := longint(1) shl ib ;
-
- i2coshdx := 2*(is + is div 4) ;
- r := 0 ;
- repeat
- { sinh and cosh }
- Dec(i2coshdx) ;
- coshdx := i2coshdx / (2*is) ;
- sinhdx := sqrt(sqr(coshdx) - 1.0) ;
- { cosine scaled Bxx }
- isinhdx := Round(sinhdx * is) ;
- { count distinct set bits }
- ni2coshdx := nBits(i2coshdx) ;
- if ni2coshdx > ib div 2 then
- ni2coshdx := ni2coshdx - ib - 2 ;
- nidx := abs(ni2coshdx) ;
- { hex strings }
- if nidx < 3 then begin
- itoh(sisinhdx,isinhdx) ;
- icoshdx := Round(coshdx * is) ;
- itoh(sicoshdx,icoshdx) ;
- itoh(si2coshdx,i2coshdx) ;
- dx := arctanh(sinhdx/coshdx) ;
- r := Round(4.0/sqr(dx)) ;
- writeln (output,dx:10:5,' ',r:5,
- ' ',sisinhdx,' ',sicoshdx,' ',si2coshdx,
- ' ',ni2coshdx:4,' ',nidx:4)
- end
- until (i2coshdx <= 2*is+1) or (r > 2000)
- end.
-
- { Copyright (C) 1988 Adam Fritz, 133 Main St., Afton, NY 13730 }