program Project1;
uses sysutils,math,crt;
const n=20000000;
numberofroutines=4;
Type TTanHFunc = function(const x: Float): Float;
var i:longint;
v:float;
SampleData,Differences:array[1..N] of Float;
results:array[1..n,1..numberofroutines] of Float;
verify:boolean=true;
BaseTime:double;
TimeInRoutine:Array[1..numberofroutines] of double;
RoutineNames:Array[1..numberofroutines] of String;
mc:integer=0;
const MaxTanh = 5678.22249441322; // Ln(MaxExtended)/2
TestMaxRange=350;
function mathtanh(const x : float) : float;
var Temp : float;
begin
if x>MaxTanh then exit(1.0)
else if x<-MaxTanh then exit (-1.0);
temp:=exp(-2*x);
mathtanh:=(1-temp)/(1+temp)
end;
function NewTanhIdea1(const x:float):float;
var SignX:Integer;
begin
SignX:=sign(x);
if SignX=0 then result:=0
else result:=SignX*(
(1-exp(((SignX*-1)*2)*x))
/
(1+exp(((SignX*-1)*2)*x)));
end;
function NewTanh2(const x:float):float;
var SignX:Integer;
begin
if X < 0 then
result:=-(1-exp(2*x))/(1+Exp(2*x)) //ie -tanh(-x) (here X < 0, tanh(x)=-tanh(-x)
else
result:=(1-exp(-2*x))/(1+Exp(-2*x)); //ie tanh(x)
end;
function JoshNewTanh(const X: float): float;
const xrange=60;
begin
if X>xrange then Result := 1.0
else
if X<-xrange then Result := -1.0
else
begin
Result := Exp(X);
Result := Result*Result;
Result := (Result-1.0)/(Result+1.0);
end;
end;
var t:tdatetime;
d:float;
tol:float=0.00000000000001;
dx:integer=48;
dy:integer=1;
procedure PrepareData;
var j,k:longint;
begin
WriteLn('Preparing Dataset');
for j:=1 to n do
begin
SampleData[j]:=random-0.5*(2*TestMaxRange);
for k:=1 to numberofroutines do results[j,k]:=0;
end;
for k:=1 to numberofroutines do differences[k]:=0;
end;
Function Test(Descr: String; TanHFunc: TTanHFunc; r:integer):Double;
var
t: TDateTime;
i: Integer;
ans:float;
begin
Write(' Testing ' + Descr + '...');
t:=Now;
for i := 1 to N do
begin
ans:=TanHFunc(SampleData[i]);
results[i,r]:=ans;
if verify then if abs(results[i,r]-results[i,1])>tol then differences[r]:=differences[r]+abs(results[i,r]-results[i,1]);
end;
t := Now - t;
if r=1 then BaseTime:=t;
WriteLn(' done: ', FormatDateTime('s.zzz', t), ' sec');
if verify then writeLn(' Differences :',differences[r]:8:8);
WriteLn;
TimeInRoutine[r]:=TimeInRoutine[r]+t;
result:=t;
end;
begin
RoutineNames[1]:='MathTanH....';
RoutineNames[2]:='NewTanh2....';
RoutineNames[3]:='NewTanhIdea1';
RoutineNames[4]:='JoshNewTanh.';
randomize;
randseed:=0;
mc:=0;
repeat
inc(mc);
PrepareData;
t:=test(RoutineNames[1],@mathtanh,1);
t:=test(RoutineNames[2],@NewTanh2,2);
t:=test(RoutineNames[3],@NewTanhIdea1,3);
t:=test(RoutineNames[4],@JoshNewTanh,4);
TextBackground(blue);
gotoxy(dx,dy);write(' Total Times Count '+mc.ToString); clreol;
gotoxy(dx,dy+1);write(' hr mn se ms Avg'); clreol;
if mc>0 then
begin
for i:=1 to numberofroutines do
begin;
gotoxy(dx,dy+1+i);
write(' '+RoutineNames[i]+':', FormatDateTime('hh.nn.ss.zzz', TimeInRoutine[i]), ' ',FormatDateTime('s.zzz',TimeInRoutine[i]/mc), ' sec'); clreol;
end;
end;
TextBackground(black);
gotoxy(1,1);
until false;
end.