separate( Test_Log_Family ) procedure Core_Test_Log(N : in Int_Type; NLog2_Lead, NLog2_Trail : in Float_Type; J, K, L, M : in Int_Type; Arg, Log_of_Arg : out Value_Table ) is X, Value, Buffer : Value_Table; My_Arg, My_Val : Value_Table; I, Abs_N, S_Ind : Int_Type; Two_to_N, Factor, S, R, Tmp, P, PM_1 : Float_Type; A, B, C, F, G, Beta : Float_Type; One : constant Float_Type := 1.0; Two : constant Float_Type := 2.0; Half : constant Float_Type := 0.5; begin --Calculate 2**N if (N >= 0) then Abs_N := N; Factor := Two; else Abs_N := -N; Factor := Half; end if; Two_to_N := One; for Index in 1..Abs_N loop Two_to_N := Factor * Two_to_N; end loop; if K = 0 then --Test for arguments in 2**N * [31/32, 33/32] PM_1 := One; for Index in 1..Value_Table_Size loop X(Index, Lead ) := PM_1 * 2#1.0#E-12 * Float_Type(J); X(Index, Trail) := PM_1 * 2#1.0#E-12 * Rand_Real; PM_1 := -PM_1; Buffer(Index, Lead ) := One + (X(Index,Lead) + X(Index,Trail)); Buffer(Index, Lead ) := Buffer(Index, Lead ) * Two_to_N; Buffer(Index, Trail) := 0.0; end loop; Normalize( Val_In => Buffer, Val_Out => Arg ); for Index in 1..Value_Table_Size loop S := Buffer(Index, Lead) / Two_to_N - One; R := S/(Two+S); P := AtanhMx_Taylor( R ); X(Index, Trail) := S - X(Index, Lead); -- at this point, Arg = 2**N(1 + S); -- 1 + S = 1 + X(lead)+X(trail) exactly Buffer(Index, Lead ) := S - Half*X(Index,Lead)*X(Index,Lead); Buffer(Index, Trail) := P + P + Half*S*S*R - Half*X(Index,Trail)* (X(Index,Lead)+S); end loop; Normalize( Val_In => Buffer, Val_Out => Value ); --the case of arguments in 2**N * [31/32, 33/32]. else --arguments in 2**N * [1/sqrt(2), sqrt(2)] not close to the center A := A_K(K); B := B_L(L); C := C_M(M); F := (A+B)*C; G := A*B*C; PM_1 := One; for Index in 1..Value_Table_Size loop P := Rand_Real * 2#1.0#E-15; X(Index, Lead ) := (One + PM_1*A)*(One + PM_1*B); X(Index, Trail) := PM_1*( C*X(Index, Lead) + P ); PM_1 := -PM_1; Buffer(Index, Lead ) := (X(Index, Lead) + X(Index, Trail))*Two_to_N; Buffer(Index, Trail) := 0.0; end loop; Normalize( Val_In => Buffer, Val_Out => Arg ); PM_1 := One; for Index in 1..Value_Table_Size loop X(Index, Trail) := Buffer(Index, Lead) / Two_to_N - X(Index, Lead); X(Index, Trail) := X(Index, Trail) - PM_1*C; X(Index, Trail) := X(Index, Trail) - F; X(Index, Trail) := X(Index, Trail) - PM_1*G; PM_1 := -PM_1; --at this point, Arg(Index) = 2**N * (Beta + X(Trail)), where --Beta = (1+hA)(1+hB)(1+hC), h is 1 or -1. end loop; --now compute log( Beta + X(Trail) ) PM_1 := One; S_Ind := 0; for Index in 1..Value_Table_Size loop Buffer(Index, Lead ) := U_K(K,S_Ind,Lead) + V_L(L,S_Ind,Lead) + W_M(M,S_Ind,Lead); Buffer(Index, Trail) := U_K(K,S_Ind,Trail) + V_L(L,S_Ind,Trail) + W_M(M,S_Ind,Trail); Beta := (One + PM_1*A) * (One + PM_1*B) * (One + PM_1*C); R := X(Index,Trail) / (Beta+Beta+X(Index,Trail)); P := Two * Atanh_Taylor( R ); Buffer(Index, Trail) := Buffer(Index, Trail) + P; PM_1 := -PM_1; S_Ind := (S_Ind + 1) mod 2; end loop; Normalize( Val_In => Buffer, Val_Out => Value ); end if; if (N = 0) then for Index in 1..Value_Table_Size loop Log_of_Arg(Index, Lead ) := Value(Index, Lead ); Log_of_Arg(Index, Trail) := Value(Index, Trail); end loop; else for Index in 1..Value_Table_Size loop Buffer(Index, Lead) := NLog2_Lead + Value(Index, Lead); end loop; for Index in 1..Value_Table_Size loop Buffer(Index, Trail) := (NLog2_Lead - Buffer(Index, Lead)) + Value(Index, Lead); Buffer(Index, Trail) := Buffer(Index, Trail) + Value(Index,Trail) + NLog2_Trail; end loop; Normalize( Val_In => Buffer, Val_Out => Log_of_Arg ); end if; return; end Core_Test_Log;