Ada Example : Zetha

This example shows the calculation of zeta. Zeta on wikipedia Some additionnal information about Queue Containers can be found here


with Ada.Exceptions;
with Ada.Text_IO;
with Ada.Float_Text_IO;
with Ada.Text_IO.Complex_IO;
with Ada.Calendar;
with Ada.Calendar.Formatting;
with Ada.Numerics.Generic_Elementary_Functions;
with Ada.Numerics.Generic_Complex_Types;
with Ada.Numerics.Generic_Complex_Elementary_Functions;
 
with Ada.Containers.Synchronized_Queue_Interfaces;
with Ada.Containers.Unbounded_Synchronized_Queues;
with System.Multiprocessors;
procedure start is
 
   package Math is new Ada.Numerics.Generic_Elementary_Functions (Long_Float);
   package ComplexPkg is new Ada.Numerics.Generic_Complex_Types (Real => Long_Float);
 
   package ComplexMath is new Ada.Numerics.Generic_Complex_Elementary_Functions (Complex_Types => ComplexPkg);
   package Complex_Text_IO is new Ada.Text_IO.Complex_IO (ComplexPkg);
 
   -- only valid if |z| > 1
   function Zetha (Z : ComplexPkg.Complex) return ComplexPkg.Complex is
      S   : ComplexPkg.Complex := ComplexPkg.Compose_From_Cartesian (0.0, 0.0);
      ONE : ComplexPkg.Complex := ComplexPkg.Compose_From_Cartesian (1.0, 0.0);
 
      K : ComplexPkg.Complex;
      use type ComplexPkg.Complex;
      use ComplexMath;
   begin
      for I in 1 .. 10_000_000 loop
         K := ComplexPkg.Compose_From_Cartesian (Long_Float (I), 0.0);
         S := S + (ONE / (K**Z));
      end loop;
      return S;
   end Zetha;
 
   type Complex_Queue_Item is record
      valid : Boolean;
      c     : ComplexPkg.Complex;
   end record;
 
   package Queue_Interface is new Ada.Containers.Synchronized_Queue_Interfaces (Complex_Queue_Item);
   package Unbound_Complex_Queue is new Ada.Containers.Unbounded_Synchronized_Queues (Queue_Interface);
 
   type Queue_Access is access all Unbound_Complex_Queue.Queue;
 
   Ct_Nb_Tack : constant Integer := Integer (System.Multiprocessors.Number_Of_CPUs);
 
   task type Task_A is
      entry Init_A (Undound_Queue : in Queue_Access);
   end Task_A;
 
   task body Task_A is
      Task_Undound_Queue : Queue_Access;
      use type Ada.Containers.Count_Type;
   begin
 
      accept Init_A (Undound_Queue : Queue_Access) do
         Task_Undound_Queue := Undound_Queue;
      end Init_A;
 
      while Task_Undound_Queue.Current_Use > 0 loop
         declare
            Item : Complex_Queue_Item := (valid => False, c => ComplexPkg.Compose_From_Cartesian (0.0, 0.0));
         begin
 
            Task_Undound_Queue.Dequeue (Item);
            if Item.valid then
               declare
                  val_input  : String (1 .. 50);
                  val_output : String (1 .. 50);
               begin
                  Complex_Text_IO.Put (val_input, Item.c);
 
                  Complex_Text_IO.Put (val_output, Zetha (Item.c));
                  Ada.Text_IO.Put_Line (val_input & "   " & val_output);
               end;
            end if;
 
         end;
      end loop;
   end Task_A;
 
   A_Array : array (0 .. Ct_Nb_Tack) of Task_A;
 
   Starting_Time    : Ada.Calendar.Time := Ada.Calendar.Clock;
   Ending_Time      : Ada.Calendar.Time;
   Program_Duration : Duration;
 
   Undound_Queue : aliased Unbound_Complex_Queue.Queue;
begin
   Ada.Text_IO.Put_Line ("--> start" & Ada.Calendar.Formatting.Image (Starting_Time, True));
 
   for J in 0 .. 200 loop
      for I in 1 .. 100 loop
         Undound_Queue.Enqueue ((valid => True, c => ComplexPkg.Compose_From_Cartesian ((Long_Float (I) / 10.0 + 1.0), Long_Float (J) / 10.0)));
      end loop;
   end loop;
 
   for I in 0 .. Ct_Nb_Tack loop
      A_Array (I).Init_A (Undound_Queue'Access);
   end loop;
 
   Ending_Time      := Ada.Calendar.Clock;
   Program_Duration := Ada.Calendar."-" (Ending_Time, Starting_Time);
   Ada.Text_IO.Put_Line ("--> duration" & Ada.Calendar.Formatting.Image (Program_Duration, True));
 
end start;