comp.lang.ada
 help / color / mirror / Atom feed
Search results ordered by [date|relevance]  view[summary|nested|Atom feed]
thread overview below | download mbox.gz: |
* Re: project euler 29
  2023-09-15  9:50  5% ` Jeffrey R.Carter
@ 2023-09-15 18:04  0%   ` Keith Thompson
  0 siblings, 0 replies; 200+ results
From: Keith Thompson @ 2023-09-15 18:04 UTC (permalink / raw)


"Jeffrey R.Carter" <spam.jrcarter.not@spam.acm.org.not> writes:
[...]
> can only be compiled with GNAT. Note that, unlike
> PragmARC.Unbounded_Numbers.Integers, GNAT's implementation of
> Ada.Numerics.Big_Numbers.Big_Integers is not truly unbounded. I don't
> know if it will hold 101 ** 101 without modification.

It only has to hold 100 ** 100.  The Python code in the parent uses the
expression `range(2,101)`.  Python's range() function yields a range
that includes the first bound and excludes the second bound.

-- 
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Will write code for food.
void Void(void) { Void(); } /* The recursive call of the void */

^ permalink raw reply	[relevance 0%]

* Re: project euler 29
  @ 2023-09-15  9:50  5% ` Jeffrey R.Carter
  2023-09-15 18:04  0%   ` Keith Thompson
  0 siblings, 1 reply; 200+ results
From: Jeffrey R.Carter @ 2023-09-15  9:50 UTC (permalink / raw)


On 2023-09-15 11:03, CSYH (QAQ) wrote:
> 
> for this problem I want to know how to know is there an easy way to store a large number like 100 ** 100, and how do U make a similar function like "set(context)" to delete the duplicated value in a vector.

You will need an unbounded-integer pkg. If you want to write portable code in a 
standard language, then you can write Ada 12 using a library such as 
PragmARC.Unbounded_Numbers.Integers 
(https://github.com/jrcarter/PragmARC/blob/Ada-12/pragmarc-unbounded_numbers-integers.ads). 
This will compile with both GNAT and ObjectAda.

If you want to write non-portable code in a non-standard, Ada-like language, 
then you can use the GNAT language, which is mostly Ada 12 with some Ada 23 
features, one of which is the Ada-23 standard package 
Ada.Numerics.Big_Numbers.Big_Integers 
(http://www.ada-auth.org/standards/22aarm/html/AA-A-5-6.html). This can only be 
compiled with GNAT. Note that, unlike PragmARC.Unbounded_Numbers.Integers, 
GNAT's implementation of Ada.Numerics.Big_Numbers.Big_Integers is not truly 
unbounded. I don't know if it will hold 101 ** 101 without modification.

You can store the results directly in a set from the standard library to avoid 
duplicate values. If I understand your Python (probably not), you would want to 
output the result of Length for the resulting set.

-- 
Jeff Carter
"I didn't squawk about the steak, dear. I
merely said I didn't see that old horse
that used to be tethered outside here."
Never Give a Sucker an Even Break
103

^ permalink raw reply	[relevance 5%]

* Re: When using the Ada Big_Numbers.Big_Integers package, can the To_String function output be sliced?
  2023-07-29 23:53  6%           ` Kenneth Wolcott
@ 2023-07-30  4:43  5%             ` Randy Brukardt
  0 siblings, 0 replies; 200+ results
From: Randy Brukardt @ 2023-07-30  4:43 UTC (permalink / raw)


'Image doesn't support any formatting, so no "Aft" or "Exp". The slicing 
isn't the problem. :-)

You can use Text_IO to write to a string if you need formatting. 'Image is 
for quick & dirty debugging, not fancy output. (Of course, if you're lucky 
and it does what you need, then feel free to use it.)

                                 Randy.

"Kenneth Wolcott" <kennethwolcott@gmail.com> wrote in message 
news:2a5702b3-dbbc-4255-a4d4-e801f227fed3n@googlegroups.com...
On Saturday, July 29, 2023 at 4:49:08?PM UTC-7, Kenneth Wolcott wrote:
> On Saturday, July 29, 2023 at 4:07:17?AM UTC-7, AdaMagica wrote:
> > > Powers_of_2 := Powers_of_2 * To_Big_Integer (2);
> > With the aspect Integer_Literal, also Powers_of_2 * 2 must work. The 
> > attributes Integer_Literal, Real_Literal, Put_Image make the new big 
> > numbers nearly work like numeric types (they are not). A difference: The 
> > range syntax for instance in loops A .. B is illegal.
> I understand that the range syntax in loops implies that the loop variable 
> is acting like an enumerated type which is not true for Big_Integers.
>
> What confused me is that I thought I had to convert the numeric literal 
> (I'll have to go back and look at the package spec again to get this 
> firmly understood.
>
> I have an another question about string slicing: I've tried (obviously 
> incorrectly) to use a variable is one of the slice integers. Can this be 
> done?
>
> Thanks,
> Ken

Apparently not :-(

gnatmake main.adb
gcc -c main.adb
main.adb:28:67: error: named parameters not permitted for attributes
     9 with Ada.Text_IO; use Ada.Text_IO;
    10 with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
    11 with Ada.Float_Text_IO; use Ada.Float_Text_IO;
    12 with Ada.Numerics.Elementary_Functions; use 
Ada.Numerics.Elementary_Functions;
    13 with Ada.Command_Line; use Ada.Command_Line;
    14
    15 procedure Main is
    16   Substr : String := Argument (1);
    17   Nth : Positive := Integer'Value (Argument (2));
    18   I, J : Natural;
    19   Temp : Float;
    20 begin
    21   I := 0;
    22   J := 0;
    23   loop
    24     I := I + 1;
    25     exit when I >= 10;
    26     Temp := 10.0 ** (log (2.0, 10.0) * Float (I));
    27     if I >= 4  then
    28       if (Float'Image (10.0 ** (log (2.0, 10.0) * Float (I)), Aft => 
0, Exp => 0) (1 .. Substr'Length) = Substr then
    29         J := J + 1;
    30         if J = Nth then
    31           Put (I, 0);
    32           New_Line;
    33           exit;
    34         end if;
    35       end if;
    36     end if;
    37   end loop;
    38 end Main;

Thanks,
Ken 


^ permalink raw reply	[relevance 5%]

* Re: When using the Ada Big_Numbers.Big_Integers package, can the To_String function output be sliced?
  @ 2023-07-29 23:53  6%           ` Kenneth Wolcott
  2023-07-30  4:43  5%             ` Randy Brukardt
  0 siblings, 1 reply; 200+ results
From: Kenneth Wolcott @ 2023-07-29 23:53 UTC (permalink / raw)


On Saturday, July 29, 2023 at 4:49:08 PM UTC-7, Kenneth Wolcott wrote:
> On Saturday, July 29, 2023 at 4:07:17 AM UTC-7, AdaMagica wrote: 
> > > Powers_of_2 := Powers_of_2 * To_Big_Integer (2); 
> > With the aspect Integer_Literal, also Powers_of_2 * 2 must work. The attributes Integer_Literal, Real_Literal, Put_Image make the new big numbers nearly work like numeric types (they are not). A difference: The range syntax for instance in loops A .. B is illegal.
> I understand that the range syntax in loops implies that the loop variable is acting like an enumerated type which is not true for Big_Integers. 
> 
> What confused me is that I thought I had to convert the numeric literal (I'll have to go back and look at the package spec again to get this firmly understood. 
> 
> I have an another question about string slicing: I've tried (obviously incorrectly) to use a variable is one of the slice integers. Can this be done? 
> 
> Thanks, 
> Ken

Apparently not :-(

gnatmake main.adb
gcc -c main.adb
main.adb:28:67: error: named parameters not permitted for attributes
     9	with Ada.Text_IO; use Ada.Text_IO;
    10	with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
    11	with Ada.Float_Text_IO; use Ada.Float_Text_IO;
    12	with Ada.Numerics.Elementary_Functions; use Ada.Numerics.Elementary_Functions;
    13	with Ada.Command_Line; use Ada.Command_Line;
    14
    15	procedure Main is
    16	  Substr : String := Argument (1);
    17	  Nth : Positive := Integer'Value (Argument (2));
    18	  I, J : Natural;
    19	  Temp : Float;
    20	begin
    21	  I := 0;
    22	  J := 0;
    23	  loop
    24	    I := I + 1;
    25	    exit when I >= 10;
    26	    Temp := 10.0 ** (log (2.0, 10.0) * Float (I));
    27	    if I >= 4  then
    28	      if (Float'Image (10.0 ** (log (2.0, 10.0) * Float (I)), Aft => 0, Exp => 0) (1 .. Substr'Length) = Substr then
    29	        J := J + 1;
    30	        if J = Nth then
    31	          Put (I, 0);
    32	          New_Line;
    33	          exit;
    34	        end if;
    35	      end if;
    36	    end if;
    37	  end loop;
    38	end Main;

Thanks,
Ken

^ permalink raw reply	[relevance 6%]

* Re: When using the Ada Big_Numbers.Big_Integers package, can the To_String function output be sliced?
  2023-07-27  8:53  6% ` Jeffrey R.Carter
@ 2023-07-27 22:47  5%   ` Kenneth Wolcott
    0 siblings, 1 reply; 200+ results
From: Kenneth Wolcott @ 2023-07-27 22:47 UTC (permalink / raw)


On Thursday, July 27, 2023 at 1:53:38 AM UTC-7, Jeffrey R.Carter wrote:
> On 2023-07-27 07:26, Kenneth Wolcott wrote: 
> > 
> > When using the Ada Big_Numbers.Big_Integers package, can the To_String function output be sliced? 
> > 
> > I'd like to slice out the first two digits from the output of the To_String function of Ada.Big_Numbers.Big_Integers. 
> > 
> > When trying to do the usual string slicing on the output I get a silent failure, it is just as if I typed the null statement.
> It would be helpful if you could show what you're doing and what results you 
> get. This 
> 
> with Ada.Numerics.Discrete_Random; 
> with Ada.Text_IO; 
> 
> procedure Func_Slice is 
> subtype Digit is Character range '0' .. '9'; 
> 
> package Random is new Ada.Numerics.Discrete_Random (Result_Subtype => Digit); 
> 
> Gen : Random.Generator; 
> 
> function Image (N : in Natural) return String is 
> (if N = 0 then "" else Random.Random (Gen) & Image (N - 1) ); 
> -- Returns a string of N random Digits 
> begin -- Func_Slice 
> Random.Reset (Gen => Gen); 
> Ada.Text_IO.Put_Line (Item => Image (10) (1 .. 2) ); 
> end Func_Slice; 
> 
> works as expected 
> 
> $ gnatmake -m -j0 -gnat12 -gnatan -gnato2 -O2 -fstack-check func_slice.adb 
> x86_64-linux-gnu-gcc-12 -c -gnat12 -gnatan -gnato2 -O2 -fstack-check func_slice.adb 
> x86_64-linux-gnu-gnatbind-12 -x func_slice.ali 
> x86_64-linux-gnu-gnatlink-12 func_slice.ali -O2 -fstack-check 
> $ ./func_slice 
> 10 
> $ ./func_slice 
> 51 

Hi Jeff;

  After going back and exhaustively reviewing the AdaCore Learning Introduction sections on Strings and Arrays, I determined that I was not slicing with the correct syntax for what I wanted to obtain, it seems that I was slicing built-in whitespace, not the digits I was looking for.  So I am now extracting the two-digit slice using (2 .. 3) rather than (1 .. 2) and I am now obtaining the desired output.  What I was trying to do was to obtain the slice from the string on the fly, not first saving the string to a variable.

This is what I have now (which works great):
---------------------------------------------------------------------------
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with Ada.Command_Line; use Ada.Command_Line;
with Ada.Numerics.Big_Numbers.Big_Integers; use Ada.Numerics.Big_Numbers.Big_Integers;

procedure Powers_Of_2_With_Leading_Digits_Of_12 is
  Max : Positive := Integer'Value (Argument (1));
  Powers_of_2 : Big_Positive := 1;
begin
  for I in 1 .. Max loop
    Powers_of_2 := Powers_of_2 * To_Big_Integer (2);
    if I >= 4 then
      declare
        Powers_of_2_in_String_Format : String := To_String (Powers_of_2);
        First_Pair_of_String_Digits : String := Powers_of_2_in_String_Format (2 .. 3);
      begin
        if First_Pair_of_String_Digits = "12" then
          Put ("2^");
          Put (I, 0);
          Put_Line (To_String (Powers_of_2));
        end if;
      end; -- declare
    end if;
  end loop;
end Powers_Of_2_With_Leading_Digits_Of_12;
---------------------------------------------------------------------------

Now I can generalize this to more closely match the task requirements.

I think I tried to incorrectly create the slice from the To_String output directly without creating the variable in which to store the slice, which then requires the declare block.

Thanks,
Ken

^ permalink raw reply	[relevance 5%]

* Re: When using the Ada Big_Numbers.Big_Integers package, can the To_String function output be sliced?
  @ 2023-07-27  8:53  6% ` Jeffrey R.Carter
  2023-07-27 22:47  5%   ` Kenneth Wolcott
  0 siblings, 1 reply; 200+ results
From: Jeffrey R.Carter @ 2023-07-27  8:53 UTC (permalink / raw)


On 2023-07-27 07:26, Kenneth Wolcott wrote:
> 
> When using the Ada Big_Numbers.Big_Integers package, can the To_String function output be sliced?
> 
>    I'd like to slice out the first two digits from the output of the To_String function of Ada.Big_Numbers.Big_Integers.
> 
>    When trying to do the usual string slicing on the output I get a silent failure, it is just as if I typed the  null statement.

It would be helpful if you could show what you're doing and what results you 
get. This

with Ada.Numerics.Discrete_Random;
with Ada.Text_IO;

procedure Func_Slice is
    subtype Digit is Character range '0' .. '9';

    package Random is new Ada.Numerics.Discrete_Random (Result_Subtype => Digit);

    Gen : Random.Generator;

    function Image (N : in Natural) return String is
       (if N = 0 then "" else Random.Random (Gen) & Image (N - 1) );
    -- Returns a string of N random Digits
begin -- Func_Slice
    Random.Reset (Gen => Gen);
    Ada.Text_IO.Put_Line (Item => Image (10) (1 .. 2) );
end Func_Slice;

works as expected

$ gnatmake -m -j0 -gnat12 -gnatan -gnato2 -O2 -fstack-check func_slice.adb
x86_64-linux-gnu-gcc-12 -c -gnat12 -gnatan -gnato2 -O2 -fstack-check func_slice.adb
x86_64-linux-gnu-gnatbind-12 -x func_slice.ali
x86_64-linux-gnu-gnatlink-12 func_slice.ali -O2 -fstack-check
$ ./func_slice
10
$ ./func_slice
51

-- 
Jeff Carter
"I would never want to belong to any club that
would have someone like me for a member."
Annie Hall
41

^ permalink raw reply	[relevance 6%]

* Re: GNAT Community 2020 (20200818-93):   Big_Integer
  @ 2023-07-08  2:58  5%   ` Randy Brukardt
  0 siblings, 0 replies; 200+ results
From: Randy Brukardt @ 2023-07-08  2:58 UTC (permalink / raw)


"Simon Wright" <simon@pushface.org> wrote in message 
news:lyr0prq19e.fsf@pushface.org...
...
> I don't know whether the ARM requires/expects Big_Integer to be
> streamable, but I think you had every reason to expect it!

See 13.13.1(54/1):

For every subtype S of a language-defined nonlimited specific type T, the 
output generated by S'Output or S'Write shall be readable by S'Input or 
S'Read, respectively. This rule applies across partitions if the 
implementation conforms to the Distributed Systems Annex.

Ada.Numerics.Big_Numbers.Big_Integers.Big_integer surely is a 
language-defined nonlimited specific type, so the above applies. Streaming 
should work, if it doesn't, that's a bug.

                 Randy.


^ permalink raw reply	[relevance 5%]

* Re: GNAT Community 2020 (20200818-93): Big_Integer
  2023-06-30 19:28  7% GNAT Community 2020 (20200818-93): Big_Integer Frank Jørgen Jørgensen
@ 2023-06-30 21:07  4% ` Dmitry A. Kazakov
    1 sibling, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2023-06-30 21:07 UTC (permalink / raw)


On 2023-06-30 21:28, Frank Jørgen Jørgensen wrote:

> I'm running the below program with GNAT Community 2020 (20200818-93)
> on Windows 11 Home.
> I have some problems trying to save big numbers to a file - so I noticed this behaviour:
> If I open Test.dat in Visual Studio Hex editor,  it seems like this program saves this big number with a different bit pattern each time.
> Is that as expected?
> I do have some problems reading back the big numbers in my real code.
> When I compile I get the warning: "Ada.Numerics.Big_Numbers.Big_Integers"  is an Ada 202x unit.
> 
> --
> with Ada.Streams.Stream_IO; use Ada.Streams.Stream_IO;
> with Ada.Numerics.Big_Numbers.Big_Integers;
> 
> procedure Test is
> 
>        B1 : Ada.Numerics.Big_Numbers.Big_Integers.Big_Integer;
>        F1 : File_Type;
>        S1 : Stream_Access;
>     begin
>        B1 := 1;
> 
>        Ada.Streams.Stream_IO.Create (F1, Out_File, "Test.dat");
>        S1 := Ada.Streams.Stream_IO.Stream (F1);
>        Ada.Numerics.Big_Numbers.Big_Integers.Big_Integer'Write(S1, B1);
>        Ada.Numerics.Big_Numbers.Big_Integers.Big_Integer'Output(S1, B1);
>        Ada.Streams.Stream_IO.Close (F1);
> end Test;

As a general rule, you should never use predefined implementations of 
stream attributes except for Stream_Element or Character. Anything else 
you must always override or else not use.

If you want to serialize signed integers use some portable format for 
it. E.g. a chained encoding.

Here is a test program for a straightforward implementation of chained 
store/restore:
-------------------------
with Ada.Streams.Stream_IO; use Ada.Streams.Stream_IO;
with Ada.Numerics.Big_Numbers.Big_Integers;
with Ada.Exceptions;
with Ada.IO_Exceptions;

procedure Test is

    use Ada.Streams;
    use Ada.Numerics.Big_Numbers.Big_Integers;
    use Ada.Exceptions;
    use Ada.Streams.Stream_IO;

    Two : constant Big_Integer := To_Big_Integer (2);

    package Conversions is new Unsigned_Conversions (Stream_Element);
    use Conversions;

    function Get
             (  Stream : in out Root_Stream_Type'Class
             )  return Big_Integer is
       Result   : Big_Integer;
       Power    : Natural := 6;
       Negative : Boolean;
       Buffer   : Stream_Element_Array (1..1);
       Last     : Stream_Element_Offset;
       This     : Stream_Element renames Buffer (1);
    begin
       Stream.Read (Buffer, Last);
       if Last /= 1 then
          raise End_Error;
       end if;
       Result   := To_Big_Integer ((This and 2#0111_1110#) / 2);
       Negative := 0 /= (This and 1);
       if 0 = (This and 16#80#) then
          if Negative then
             return -Result - 1;
          else
             return Result;
          end if;
       end if;
       loop
          Stream.Read (Buffer, Last);
          if Last /= 1 then
             raise End_Error;
          end if;
          Result := Result +
             Two**Power * To_Big_Integer (This and 16#7F#);
          if 0 = (This and 16#80#) then
             if Negative then
                return -Result - 1;
             else
                return Result;
             end if;
          end if;
          Power := Power + 7;
       end loop;
    end Get;

    procedure Put
              (  Stream : in out Root_Stream_Type'Class;
                 Value  : Big_Integer
              )  is
       Item   : Big_Integer := Value;
       Buffer : Stream_Element_Array (1..1);
       This   : Stream_Element renames Buffer (1);
    begin
       if Item >= 0 then
          Item := Value;
          This := From_Big_Integer (Item mod (16#40#)) * 2;
       else
          Item := -(Value + 1);
          This := From_Big_Integer (Item mod (16#40#)) * 2 + 1;
       end if;
       Item := Item / 16#40#;
       if Item = 0 then
          Stream.Write (Buffer);
          return;
       end if;
       This := This or 16#80#;
       Stream.Write (Buffer);
       loop
          This := From_Big_Integer (Item mod 16#80#) or 16#80#;
          Item := Item / 16#80#;
          if Item = 0 then
             This := This and 16#7F#;
             Stream.Write (Buffer);
             return;
          end if;
          Stream.Write (Buffer);
       end loop;
    end Put;

    F : File_Type;
begin
    Create (F, Out_File, "Test.dat");
    for I in -1_000_000..1_000_000 loop
       Put (Stream (F).all, To_Big_Integer (I));
    end loop;
    Close (F);
    Open (F, In_File, "Test.dat");
    for I in -1_000_000..1_000_000 loop
       declare
          Value : constant Big_Integer := Get (Stream (F).all);
       begin
          if Value /= To_Big_Integer (I) then
             raise Data_Error;
          end if;
       end;
    end loop;
    Close (F);
end Test;
-------------------------
The above could be optimized to work with buffers rather than 
reading/writing stream octets one by one. It is a long story, but 
normally you would implement some data blocks with the length count on 
top of the stream in order to avoid inefficient octet by octet reading 
and add an error correction layer.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[relevance 4%]

* GNAT Community 2020 (20200818-93):   Big_Integer
@ 2023-06-30 19:28  7% Frank Jørgen Jørgensen
  2023-06-30 21:07  4% ` Dmitry A. Kazakov
    0 siblings, 2 replies; 200+ results
From: Frank Jørgen Jørgensen @ 2023-06-30 19:28 UTC (permalink / raw)


Hi

I'm running the below program with GNAT Community 2020 (20200818-93)
on Windows 11 Home.
I have some problems trying to save big numbers to a file - so I noticed this behaviour:
If I open Test.dat in Visual Studio Hex editor,  it seems like this program saves this big number with a different bit pattern each time.
Is that as expected?
I do have some problems reading back the big numbers in my real code.
When I compile I get the warning: "Ada.Numerics.Big_Numbers.Big_Integers"  is an Ada 202x unit.

Frank

--
with Ada.Streams.Stream_IO; use Ada.Streams.Stream_IO;
with Ada.Numerics.Big_Numbers.Big_Integers;

procedure Test is

      B1 : Ada.Numerics.Big_Numbers.Big_Integers.Big_Integer;
      F1 : File_Type;
      S1 : Stream_Access;
   begin
      B1 := 1;

      Ada.Streams.Stream_IO.Create (F1, Out_File, "Test.dat");
      S1 := Ada.Streams.Stream_IO.Stream (F1);
      Ada.Numerics.Big_Numbers.Big_Integers.Big_Integer'Write(S1, B1);
      Ada.Numerics.Big_Numbers.Big_Integers.Big_Integer'Output(S1, B1);
      Ada.Streams.Stream_IO.Close (F1);
end Test;

^ permalink raw reply	[relevance 7%]

* Re: Real_Arrays on heap with overloaded operators and clean syntax
  2023-01-23  1:14  6%           ` Leo Brewin
@ 2023-01-23  6:01  0%             ` Jim Paloander
  0 siblings, 0 replies; 200+ results
From: Jim Paloander @ 2023-01-23  6:01 UTC (permalink / raw)


On Monday, January 23, 2023 at 2:14:58 AM UTC+1, Leo Brewin wrote:
> Here is a slight variation on the solution suggested by Gautier. It uses 
> Aad's "rename" syntax so that you can avoid all the .all stuff. I use 
> this construction extensively in my large scale scientific computations. 
> 
> with Ada.Numerics.Generic_Real_Arrays; 
> with Ada.Unchecked_Deallocation;
> procedure Test_Large is 
> 
> type Float_15 is digits 15; 
> 
> package F15_R_A is new Ada.Numerics.Generic_Real_Arrays (Float_15); 
> 
> use F15_R_A; 
> 
> procedure Solve_it 
> (x : in Real_Vector; 
> y : out Real_Vector; 
> A : in Real_Matrix) is 
> begin 
> null; -- Here, the big number-crunching 
> end; 
> 
> n : constant := 10_000; 
> 
> type Vector_Access is access Real_Vector; 
> type Matrix_Access is access Real_Matrix;
> x_ptr, y_ptr : Vector_Access := new Real_Vector (1 .. n); 
> A_ptr : Matrix_Access := new Real_Matrix (1 .. n, 1 .. n); 
> 
> x : Real_Vector renames x_ptr.all; 
> y : Real_Vector renames y_ptr.all; 
> A : Real_Matrix renames A_ptr.all; 
> 
> procedure FreeVector is new 
> Ada.Unchecked_Deallocation (Real_Vector,Vector_Access); 
> procedure FreeMatrix is new 
> Ada.Unchecked_Deallocation (Real_Matrix,Matrix_Access); 
> 
> begin 
> Solve_it (x, y, A); 
> -- Deallocation here 
> FreeVector (x_ptr); 
> FreeVector (y_ptr); 
> FreeMatrix (A_ptr); 
> end;

Thank you very much, would a       for Real_Vector_Access'Storage_Pool use localPool; save you from the need to free the vectors and matrix yourself?

On the other hand, is there any  way of avoiding temporaries? Possibly a modern version of the Real_Array using expression generic syntax or something similar? Since you are using scientific computationas extensively, you must be aware of Fortran. Have you compared Fortran's complex numbers with ADA's for inner products or similar computations to see who is faster? You see, I like a lot of things about ADA, but the syntax is really difficult to follow. Sometimes it gives me the impression that it is more difficult than really needed to be. For example there should be a way for Real_Arrays to allocate memory internally and not on the stack directly like containers. And for containers to provide an indexer Vector(i) and overloaded operators similarly to Real_Vectors. But the fact that they do not give me the impression that this Language although being designed by the army for mission critical applications never realized that modern mission critical need to simplify mathematical calculations providing an easy syntax. I am surprised that after so many years and so many updates to the Standard the designers of the Language did not realized that such mathematical syntax should be simplified to attract more people from scientific computing, who are tired with Fortran 10000 ways of declaring something a variable.

^ permalink raw reply	[relevance 0%]

* Re: Real_Arrays on heap with overloaded operators and clean syntax
  2023-01-22 23:14  6%         ` Gautier write-only address
@ 2023-01-23  1:14  6%           ` Leo Brewin
  2023-01-23  6:01  0%             ` Jim Paloander
  0 siblings, 1 reply; 200+ results
From: Leo Brewin @ 2023-01-23  1:14 UTC (permalink / raw)


Here is a slight variation on the solution suggested by Gautier. It uses 
Aad's "rename" syntax so that you can avoid all the .all stuff. I use 
this construction extensively in my large scale scientific computations.

with Ada.Numerics.Generic_Real_Arrays;
with Ada.Unchecked_Deallocation;

procedure Test_Large is

   type Float_15 is digits 15;

   package F15_R_A is new Ada.Numerics.Generic_Real_Arrays (Float_15);

   use F15_R_A;

   procedure Solve_it
     (x : in     Real_Vector;
      y :    out Real_Vector;
      A : in     Real_Matrix) is
   begin
     null;  --  Here, the big number-crunching
   end;

   n : constant := 10_000;

   type Vector_Access is access Real_Vector;
   type Matrix_Access is access Real_Matrix;

   x_ptr, y_ptr : Vector_Access := new Real_Vector (1 .. n);
   A_ptr        : Matrix_Access := new Real_Matrix (1 .. n, 1 .. n);

   x : Real_Vector renames x_ptr.all;
   y : Real_Vector renames y_ptr.all;
   A : Real_Matrix renames A_ptr.all;

   procedure FreeVector is new
      Ada.Unchecked_Deallocation (Real_Vector,Vector_Access);
   procedure FreeMatrix is new
      Ada.Unchecked_Deallocation (Real_Matrix,Matrix_Access);

begin
   Solve_it (x, y, A);
   -- Deallocation here
   FreeVector (x_ptr);
   FreeVector (y_ptr);
   FreeMatrix (A_ptr);
end;

^ permalink raw reply	[relevance 6%]

* Re: Real_Arrays on heap with overloaded operators and clean syntax
  @ 2023-01-22 23:14  6%         ` Gautier write-only address
  2023-01-23  1:14  6%           ` Leo Brewin
  0 siblings, 1 reply; 200+ results
From: Gautier write-only address @ 2023-01-22 23:14 UTC (permalink / raw)


Note that Real_Arrays does not specify where things are allocated (heap or stack).
Only when you define "x : Real_Vector (1 .. n)", it is on stack. You can always write something like the snippet below.
Anyway, after a certain size, you may have to find compromises, like avoiding operators (they do too many allocations & deallocations in the background, even assuming elegant heap-allocated objects) and also give up plain matrices, against sparse matrices or band-stored matrices, typically for solving Partial Differential Equations.

with Ada.Numerics.Generic_Real_Arrays;

procedure Test_Large is

  type Float_15 is digits 15;

  package F15_R_A is new Ada.Numerics.Generic_Real_Arrays (Float_15);

  use F15_R_A;

  procedure Solve_it
    (x : in     Real_Vector;
     y :    out Real_Vector;
     A : in     Real_Matrix) is
  begin
    null;  --  Here, the big number-crunching
  end;
  
  n : constant := 10_000;

  type Vector_Access is access Real_Vector;
  type Matrix_Access is access Real_Matrix;

  x, y : Vector_Access := new Real_Vector (1 .. n);
  A    : Matrix_Access := new Real_Matrix (1 .. n, 1 .. n);
  
begin
  Solve_it (x.all, y.all, A.all);
  --  !! Deallocation here
end;

^ permalink raw reply	[relevance 6%]

* Ada Developer Room at FOSDEM 2022 - videos online
@ 2022-02-20 14:23  4% Dirk Craeynest
  0 siblings, 0 replies; 200+ results
From: Dirk Craeynest @ 2022-02-20 14:23 UTC (permalink / raw)


-----------------------------------------------------------------------

      *** Presentations and video recordings available online ***

                 11th Ada Developer Room at FOSDEM 2022

     held on Sunday 6 February 2022, online from Brussels, Belgium

              https://fosdem.org/2022/schedule/track/ada/

-----------------------------------------------------------------------

All presentations and video recordings from the 11th Ada Developer
Room, held at the online FOSDEM 2022 event recently, are available.
Yet another full day with 13 Ada-related talks by 12 authors from
8 countries!

Program overview:

- Introduction to the Ada DevRoom,
    by Fernando Oleo Blanco, Germany
- Introduction to Ada for Beginning and Experienced Programmers,
    by Jean-Pierre Rosen, France
- Ada Looks Good, Now Program a Game Without Knowing Anything,
    by Stefan Hild, Germany
- The Ada Numerics Model,
    by Jean-Pierre Rosen, France
- 2022 Alire Update,
    by Fabien Chouteau, France, Alejandro Mosteo, Spain
- SweetAda: Lightweight Development Framework for Ada-based Software
    Systems, by Gabriele Galeotti, Italy
- Use (and Abuse?) of Ada 2022 Features to Design a JSON-like Data
    Structure, by Alejandro Mosteo, Spain
- Getting Started with AdaWebPack,
    by Max Reznik, Ukraine
- Overview of Ada GUI,
    by Jeffrey Carter, Belgium
- SPARKNaCl: a Verified, Fast Re-implementation of TweetNaCl,
    by Roderick Chapman, UK
- The Outsider's Guide to Ada: Lessons from Learning Ada in 2021,
    by Paul Jarrett, USA
- Proving the Correctness of the GNAT Light Runtime Library,
    by Yannick Moy, France
- Implementing a Build Manager in Ada,
    by Stephane Carrez, France
- Exporting Ada Software to Python and Julia,
    by Jan Verschelde, USA
- Closing of the Ada DevRoom,
    by Dirk Craeynest, Belgium, Fernando Oleo Blanco, Germany

Thanks once more to all presenters and helpers for their work and
collaboration, thanks to Fer for coordinating the DevRoom, thanks
to all the FOSDEM organizers and volunteers, thanks to the many
participants for their interest, and thanks to everyone for another
nice experience!

#AdaFOSDEM #AdaDevRoom #AdaProgramming
#AdaBelgium #AdaEurope #FOSDEM2022

-----------------------------------------------------------------------

Dirk Craeynest, FOSDEM Ada DevRoom team
Dirk.Craeynest@cs.kuleuven.be (for Ada-Belgium/Ada-Europe/SIGAda/WG9)
(V20220220.1)

^ permalink raw reply	[relevance 4%]

* Ada Developer Room at FOSDEM 2022 - Sun 6 Feb - online
@ 2022-02-03 20:14  3% Dirk Craeynest
  0 siblings, 0 replies; 200+ results
From: Dirk Craeynest @ 2022-02-03 20:14 UTC (permalink / raw)


-----------------------------------------------------------------------

                         Call for Participation

                 11th Ada Developer Room at FOSDEM 2022

         Sunday 6 February 2022, online from Brussels, Belgium

    Organized in cooperation with Ada-Belgium [1] and Ada-Europe [2]

                  fosdem.org/2022/schedule/track/ada/
   www.cs.kuleuven.be/~dirk/ada-belgium/events/22/220206-fosdem.html

                 #AdaFOSDEM #AdaDevRoom #AdaProgramming
                   #AdaBelgium #AdaEurope #FOSDEM2022

-----------------------------------------------------------------------

FOSDEM [3], the Free and Open source Software Developers' European
Meeting, is a non-commercial two-day weekend event organized early
each year in Brussels, Belgium.  It is highly developer-oriented and
brings together 8000+ participants from all over the world.  The 2022
edition takes place on Saturday 5 and Sunday 6 February.  It is free
to attend and no registration is necessary.  This year, for obvious
reasons, it has been turned into an online event, just like last year.

In this edition, the Ada FOSDEM community organizes once more 8
hours of presentations related to Ada and Free or Open Software in a
s.c. Developer Room.  The "Ada DevRoom" at FOSDEM 2022 is held on the
2nd day of the event, and offers introductory presentations on the
Ada programming language, as well as more specialised presentations
on focused topics, tools and projects: a total of 13 Ada-related
presentations by 12 authors from 8 countries!

Program overview:

- Introduction to the Ada DevRoom,
    by Fernando Oleo Blanco, Germany
- Introduction to Ada for Beginning and Experienced Programmers,
    by Jean-Pierre Rosen, France
- Ada Looks Good, Now Program a Game Without Knowing Anything,
    by Stefan Hild, Germany
- The Ada Numerics Model,
    by Jean-Pierre Rosen, France
- 2022 Alire Update,
    by Fabien Chouteau, France, Alejandro Mosteo, Spain
- SweetAda: Lightweight Development Framework for Ada-based Software
    Systems, by Gabriele Galeotti, Italy
- Use (and Abuse?) of Ada 2022 Features to Design a JSON-like Data
    Structure, by Alejandro Mosteo, Spain
- Getting Started with AdaWebPack,
    by Max Reznik, Ukraine
- Overview of Ada GUI,
    by Jeffrey Carter, Belgium
- SPARKNaCl: a Verified, Fast Re-implementation of TweetNaCl,
    by Roderick Chapman, UK
- The Outsider's Guide to Ada: Lessons from Learning Ada in 2021,
    by Paul Jarrett, USA
- Proving the Correctness of the GNAT Light Runtime Library,
    by Yannick Moy, France
- Implementing a Build Manager in Ada,
    by Stephane Carrez, France
- Exporting Ada Software to Python and Julia,
    by Jan Verschelde, USA
- Closing of the Ada DevRoom,
    by Dirk Craeynest, Belgium, Fernando Oleo Blanco, Germany

The Ada at FOSDEM 2022 web-page will have all details, such as the
full schedule, abstracts of presentations, biographies of speakers,
and pointers to more info, including live video streaming and chat,
plus recordings afterwards.  For the latest information at any time,
contact Fernando Oleo Blanco <irvise@irvise.xyz>, or see:

[1] http://www.cs.kuleuven.be/~dirk/ada-belgium/
[2] http://www.ada-europe.org/
[3] https://fosdem.org/2022/

-----------------------------------------------------------------------

Dirk Craeynest, FOSDEM Ada DevRoom team
Dirk.Craeynest@cs.kuleuven.be (for Ada-Belgium/Ada-Europe/SIGAda/WG9)

(V20220203.1)

^ permalink raw reply	[relevance 3%]

* Re: Ada.Numerics.Big_Numbers.Big_Integer has a limit of 300 digits?
  2021-12-23 15:48  6% ` Jeffrey R.Carter
@ 2021-12-24  9:09 13%   ` AdaMagica
  0 siblings, 0 replies; 200+ results
From: AdaMagica @ 2021-12-24  9:09 UTC (permalink / raw)


with Ada.Numerics.Big_Numbers.Big_Integers;
use  Ada.Numerics.Big_Numbers.Big_Integers;
procedure Ausprobieren is
  I: Big_Integer := (1E1000 + 1) / 3;
  S: String      := I'Image;
begin
  Put_Line (S'Last'Image);
  Put_Line (I'Image);
end Ausprobieren;

No problem here.

^ permalink raw reply	[relevance 13%]

* Re: Ada.Numerics.Big_Numbers.Big_Integer has a limit of 300 digits?
  2021-12-22  5:57 11% Ada.Numerics.Big_Numbers.Big_Integer has a limit of 300 digits? Michael Ferguson
                   ` (2 preceding siblings ...)
  2021-12-22 17:01  6% ` Luke A. Guest
@ 2021-12-23 15:48  6% ` Jeffrey R.Carter
  2021-12-24  9:09 13%   ` AdaMagica
  3 siblings, 1 reply; 200+ results
From: Jeffrey R.Carter @ 2021-12-23 15:48 UTC (permalink / raw)


On 2021-12-22 06:57, Michael Ferguson wrote:
> 
> I was under the impression that this library would be able to infinitely calculate numbers of any length, but there is clearly a default limit of 300 digits.

As it appears from the rest of the discussion that there is a limit in the 
implementation of the pkg, you could try using PragmARC.Unbounded_Numbers.Integers

https://github.com/jrcarter/PragmARC/blob/Ada-12/pragmarc-unbounded_numbers-integers.ads

where the implementation restricts a number to Integer'Last "digits" or the 
available heap memory, whichever is less.

Note that with recent versions of GNAT for 64-bit processors, the "digits" will 
be 64 bits.

-- 
Jeff Carter
"There's no messiah here. There's a mess all right, but no messiah."
Monty Python's Life of Brian
84

^ permalink raw reply	[relevance 6%]

* Re: Ada.Numerics.Big_Numbers.Big_Integer has a limit of 300 digits?
  2021-12-23 12:18  5%             ` Niklas Holsti
@ 2021-12-23 14:01  6%               ` Ben Bacarisse
  0 siblings, 0 replies; 200+ results
From: Ben Bacarisse @ 2021-12-23 14:01 UTC (permalink / raw)


Niklas Holsti <niklas.holsti@tidorum.invalid> writes:

> In my imperfect understanding, intrinsically modular big-number
> computations can be much more efficient than such post-computation
> applications of "mod", at least if the modulus is not itself a big
> number.

Yes, there are efficient algorithms for "x * y mod n" so almost all "big
num" libraries provide a function to do it.  Ada has the type system for
the mod operation to be explicit in the type.

-- 
Ben.

^ permalink raw reply	[relevance 6%]

* Re: Ada.Numerics.Big_Numbers.Big_Integer has a limit of 300 digits?
  2021-12-23 11:41  6%           ` AdaMagica
@ 2021-12-23 12:18  5%             ` Niklas Holsti
  2021-12-23 14:01  6%               ` Ben Bacarisse
  0 siblings, 1 reply; 200+ results
From: Niklas Holsti @ 2021-12-23 12:18 UTC (permalink / raw)


On 2021-12-23 13:41, AdaMagica wrote:
> Niklas Holsti schrieb am Mittwoch, 22. Dezember 2021 um 20:05:21 UTC+1:
>> However, the
>> Big_Integers package does not directly support computations "mod"
> 
> It does A.5.6(18/5).


Yes, there is a "mod" operator for Big_Integer. My point was that there 
are no Big_Integer operations, such as multiplication, that are 
intrinsically modular in the same way as the operations for modular 
types are. So the only way to perform a modular multiplication of 
Big_Integers is to first multiply the numbers in the usual way, 
producing a possibly very large product, and then apply "mod" to reduce 
that product.

In my imperfect understanding, intrinsically modular big-number 
computations can be much more efficient than such post-computation 
applications of "mod", at least if the modulus is not itself a big number.

^ permalink raw reply	[relevance 5%]

* Re: Ada.Numerics.Big_Numbers.Big_Integer has a limit of 300 digits?
  2021-12-22 19:05  4%         ` Niklas Holsti
  2021-12-23  8:31  6%           ` Luke A. Guest
@ 2021-12-23 11:41  6%           ` AdaMagica
  2021-12-23 12:18  5%             ` Niklas Holsti
  1 sibling, 1 reply; 200+ results
From: AdaMagica @ 2021-12-23 11:41 UTC (permalink / raw)


Niklas Holsti schrieb am Mittwoch, 22. Dezember 2021 um 20:05:21 UTC+1:
> However, the 
> Big_Integers package does not directly support computations "mod"

It does A.5.6(18/5).

^ permalink raw reply	[relevance 6%]

* Re: Ada.Numerics.Big_Numbers.Big_Integer has a limit of 300 digits?
  2021-12-23  8:31  6%           ` Luke A. Guest
@ 2021-12-23  8:54  6%             ` Dmitry A. Kazakov
  0 siblings, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2021-12-23  8:54 UTC (permalink / raw)


On 2021-12-23 09:31, Luke A. Guest wrote:
> On 22/12/2021 19:05, Niklas Holsti wrote:
> 
>> Big_Integers package does not directly support computations "mod" 
>> something (perhaps this should be an extension in a later Ada 
>> standard, because such computations are quite common).
> 
> Is mod overloadable?

It is as any operator.

P.S. For large numbers one needs rather full division than separate /, 
mod, rem.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[relevance 6%]

* Re: Ada.Numerics.Big_Numbers.Big_Integer has a limit of 300 digits?
  2021-12-22 19:05  4%         ` Niklas Holsti
@ 2021-12-23  8:31  6%           ` Luke A. Guest
  2021-12-23  8:54  6%             ` Dmitry A. Kazakov
  2021-12-23 11:41  6%           ` AdaMagica
  1 sibling, 1 reply; 200+ results
From: Luke A. Guest @ 2021-12-23  8:31 UTC (permalink / raw)


On 22/12/2021 19:05, Niklas Holsti wrote:

> Big_Integers package does not directly support computations "mod" 
> something (perhaps this should be an extension in a later Ada standard, 
> because such computations are quite common).

Is mod overloadable?

^ permalink raw reply	[relevance 6%]

* Re: Ada.Numerics.Big_Numbers.Big_Integer has a limit of 300 digits?
  2021-12-22 19:26  6%     ` Mark Lorenzen
@ 2021-12-22 20:43  6%       ` Niklas Holsti
  0 siblings, 0 replies; 200+ results
From: Niklas Holsti @ 2021-12-22 20:43 UTC (permalink / raw)


On 2021-12-22 21:26, Mark Lorenzen wrote:
> On Wednesday, December 22, 2021 at 6:27:57 PM UTC+1, Michael Ferguson
> wrote:
>> On Wednesday, December 22, 2021 at 11:02:03 AM UTC-6, Luke A. Guest
>> wrote:
>>> On 22/12/2021 05:57, Michael Ferguson wrote:
>>>> I just started using the Big_Integer library that is a part of
>>>> the 202X version of ADA.
>>>> 
>>>> It is repeatedly described as an "arbitrary precision library"
>>>> that has user defined implementation.
>>>> 
>>>> I was under the impression that this library would be able to
>>>> infinitely calculate numbers of any length, but there is
>>>> clearly a default limit of 300 digits.
>>> What are you doing that requires that number of digits?
>> I am working on ProjectEuler.net problem number 48.
>> 
>> The questions asks you to sum the numbers n^n for (2 <= n <= 1000)
>> and determine what the last ten digits of this number are.
> 
> Interesting. Assume that the problem is related to the maximum size
> of lexical elements, can't you then use the "rem" function from
> Big_Integers to determine the last 10 digits e.g. by something like
> this Last_10_Digits = My_Very_Large_Number rem To_Big_Integer(1) **
> 10?


You no doubt meant To_Big_Integer (10), not To_Big_Integer(1).

But it should be possible to write directly "... rem 10_000_000_000", 
and even if that constant is too large for the Integer type, because 
Big_Integer has the Integer_Literal aspect (assuming GNAT already 
implements it).

^ permalink raw reply	[relevance 6%]

* Re: Ada.Numerics.Big_Numbers.Big_Integer has a limit of 300 digits?
  2021-12-22 17:27  5%   ` Michael Ferguson
                       ` (3 preceding siblings ...)
  2021-12-22 20:31  6%     ` Paul Rubin
@ 2021-12-22 20:39  6%     ` Paul Rubin
  4 siblings, 0 replies; 200+ results
From: Paul Rubin @ 2021-12-22 20:39 UTC (permalink / raw)


Michael Ferguson <michaelblakeferguson@gmail.com> writes:
> However, my code strictly breaks when the loop range is set to 683,
> which 683^683 = 8.12E1935.
>
> So, that is interesting that the Big_Integer type works numbers of
> just under 2000 digit length despite Bignum_Limit : constant := 200.

I wonder if the limit is 6400 bits (200 * 32 bit words) or something
related to that.  2**6400 is roughly 3.9e1926 if my math is right.

^ permalink raw reply	[relevance 6%]

* Re: Ada.Numerics.Big_Numbers.Big_Integer has a limit of 300 digits?
  2021-12-22 11:14  6% ` AdaMagica
  2021-12-22 11:32  6%   ` AdaMagica
  2021-12-22 16:04  6%   ` AdaMagica
@ 2021-12-22 20:34  6%   ` Simon Wright
  2 siblings, 0 replies; 200+ results
From: Simon Wright @ 2021-12-22 20:34 UTC (permalink / raw)


AdaMagica <christ-usch.grein@t-online.de> writes:

> There is a limit
> Bignum_Limit : constant := 200;
> in System.Generic_Bignums body, function Normalize, lines 1100ff.

This is the maximum length of a Digit_Vector, where

   subtype SD is Interfaces.Unsigned_32;
   --  Single length digit

   type Digit_Vector is array (Length range <>) of SD;
   --  Represent digits of a number (most significant digit first)

I think this should give a maximum value of ~10**2000.

I printed out sum'image'length; the last value before the exception was
1937.

^ permalink raw reply	[relevance 6%]

* Re: Ada.Numerics.Big_Numbers.Big_Integer has a limit of 300 digits?
  2021-12-22 17:27  5%   ` Michael Ferguson
                       ` (2 preceding siblings ...)
  2021-12-22 19:26  6%     ` Mark Lorenzen
@ 2021-12-22 20:31  6%     ` Paul Rubin
  2021-12-22 20:39  6%     ` Paul Rubin
  4 siblings, 0 replies; 200+ results
From: Paul Rubin @ 2021-12-22 20:31 UTC (permalink / raw)


Michael Ferguson <michaelblakeferguson@gmail.com> writes:
> I am working on ProjectEuler.net problem number 48. ...
> Obviously, this is quite a trivial problem when using any arbitrary
> precision library.

The thing about Euler problems is they usually want you to figure out a
clever math trick to get to the solution, rather than using brute
calculation.  In the case of this problem, you want to reduce all the
intermediate results mod 1e10 (which fits in an int64 easily, though not
quite in an int32).  That gets rid of the need for bignums.

^ permalink raw reply	[relevance 6%]

* Re: Ada.Numerics.Big_Numbers.Big_Integer has a limit of 300 digits?
  2021-12-22 17:27  5%   ` Michael Ferguson
  2021-12-22 17:43  6%     ` Ben Bacarisse
  2021-12-22 17:48 11%     ` Niklas Holsti
@ 2021-12-22 19:26  6%     ` Mark Lorenzen
  2021-12-22 20:43  6%       ` Niklas Holsti
  2021-12-22 20:31  6%     ` Paul Rubin
  2021-12-22 20:39  6%     ` Paul Rubin
  4 siblings, 1 reply; 200+ results
From: Mark Lorenzen @ 2021-12-22 19:26 UTC (permalink / raw)


On Wednesday, December 22, 2021 at 6:27:57 PM UTC+1, Michael Ferguson wrote:
> On Wednesday, December 22, 2021 at 11:02:03 AM UTC-6, Luke A. Guest wrote: 
> > On 22/12/2021 05:57, Michael Ferguson wrote: 
> > > I just started using the Big_Integer library that is a part of the 202X version of ADA. 
> > > 
> > > It is repeatedly described as an "arbitrary precision library" that has user defined implementation. 
> > > 
> > > I was under the impression that this library would be able to infinitely calculate numbers of any length, but there is clearly a default limit of 300 digits. 
> > What are you doing that requires that number of digits?
> I am working on ProjectEuler.net problem number 48. 
> 
> The questions asks you to sum the numbers n^n for (2 <= n <= 1000) and determine what the last ten digits of this number are. 

Interesting. Assume that the problem is related to the maximum size of lexical elements, can't you then use the "rem" function from Big_Integers to determine the last 10 digits e.g. by something like this Last_10_Digits = My_Very_Large_Number rem To_Big_Integer(1) ** 10?

This should give you a value of type Valid_Big_Integer consisting of up to ten digits that you can obtain the integer representation of.

Regards,
Mark L

^ permalink raw reply	[relevance 6%]

* Re: Ada.Numerics.Big_Numbers.Big_Integer has a limit of 300 digits?
  2021-12-22 18:02 10%       ` Michael Ferguson
@ 2021-12-22 19:05  4%         ` Niklas Holsti
  2021-12-23  8:31  6%           ` Luke A. Guest
  2021-12-23 11:41  6%           ` AdaMagica
  0 siblings, 2 replies; 200+ results
From: Niklas Holsti @ 2021-12-22 19:05 UTC (permalink / raw)


On 2021-12-22 20:02, Michael Ferguson wrote:
> On Wednesday, December 22, 2021 at 11:48:46 AM UTC-6, Niklas Holsti
> wrote:
>> On 2021-12-22 19:27, Michael Ferguson wrote:
>>> On Wednesday, December 22, 2021 at 11:02:03 AM UTC-6, Luke A.
>>> Guest wrote:
>>>> On 22/12/2021 05:57, Michael Ferguson wrote:
>>>>> I just started using the Big_Integer library that is a part
>>>>> of the 202X version of ADA.
>>>>> 


    [snip]


> Not 100% sure what modular types are


Types declared with "mod N" instead of "range A .. B", as in:

    type Eight_Bits is mod 256;

which declares an unsigned type with a range 0 .. 255 and wrap-around
arithmetic.

Modular types are not connected to Big_Integers, except that the
particular problem you are trying to solve could be computed "mod 
10**10" because it asks for only the last 10 digits. However, the 
Big_Integers package does not directly support computations "mod" 
something (perhaps this should be an extension in a later Ada standard, 
because such computations are quite common).

Using "mod 10**10" operations in solving the problem would limit the
number of digits in all intermediate results drastically.


> but I did try to do something like the following
> 
> subtype VeryBigInteger is Big_Integer range 0 .. 10E10000;
> 
> which gave "error: incorrect constraint for this kind of type"


Indeed, such a range constraint is valid only for (visibly) scalar
types, which Big_Integer is not (it is a private type).


> Niklas also gave me an epiphany as the exact error my program gives
> for the upper limit is
> 
> raised STORAGE_ERROR :
> Ada.Numerics.Big_Numbers.Big_Integers.Bignums.Normalize: big integer
> limit exceeded
> 
> I had thought that since the end of this error said big integer limit
> exceeded it was a problem with the library, but now I'm starting to
> think I need to get GNAT to allocated more memory for the program.


Perhaps. However, the very specific exception message ("big integer 
limit exceeded") suggests that this exception is not a typical 
Storage_Error (say, heap or stack exhaustion) but may indeed stem from 
exceeding some specific limit in the current Big_Integer implementation 
in GNAT.

The size of your problem, with only a few thousand digits, suggests that 
heap exhaustion is unlikely to happen. However, if the Big_Integer 
computations are internally recursive, and use stack-allocated local 
variables, stack overflow could happen, so the first thing to try would 
be to increase the stack size. Unfortunately, for the main subprogram 
that has to be done with some compiler or linker options which I don't 
recall now. (We should really extend pragma Storage_Size to apply also 
to the environment task, by specifying it for the main subprogram!)

^ permalink raw reply	[relevance 4%]

* Re: Ada.Numerics.Big_Numbers.Big_Integer has a limit of 300 digits?
  2021-12-22 17:48 11%     ` Niklas Holsti
@ 2021-12-22 18:02 10%       ` Michael Ferguson
  2021-12-22 19:05  4%         ` Niklas Holsti
  0 siblings, 1 reply; 200+ results
From: Michael Ferguson @ 2021-12-22 18:02 UTC (permalink / raw)


On Wednesday, December 22, 2021 at 11:48:46 AM UTC-6, Niklas Holsti wrote:
> On 2021-12-22 19:27, Michael Ferguson wrote: 
> > On Wednesday, December 22, 2021 at 11:02:03 AM UTC-6, Luke A. Guest wrote: 
> >> On 22/12/2021 05:57, Michael Ferguson wrote: 
> >>> I just started using the Big_Integer library that is a part of the 202X version of ADA. 
> >>> 
> >>> It is repeatedly described as an "arbitrary precision library" 
> >>> that has user defined implementation.
> Surely not "user defined"? Possibly "implementation defined".
> >>> I was under the impression that this library would be able to 
> >>> infinitely calculate numbers of any length,
> I have the same impression (up to Storage_Error, of course).
> >> but there is clearly a default limit of 300 digits. 
> >> What are you doing that requires that number of digits? 
> > 
> > I am working on ProjectEuler.net problem number 48. 
> > 
> > The questions asks you to sum the numbers n^n for (2 <= n <= 1000) 
> > and determine what the last ten digits of this number are. 
> > 
> > Obviously, this is quite a trivial problem when using any arbitrary 
> > precision library. 
> > 
> > I had incorrectly determined that 700^700 had 300 digits, in fact 
> > 700^700 = 3.7E1991. 
> > 
> > However, my code strictly breaks when the loop range is set to 683, 
> > which 683^683 = 8.12E1935.
> How does it break? Some exception, or something else? 
> 
> Mark Lorenzen suggested in an earlier post that the limit might be in 
> the Big_Integer'Image function. The package 
> Ada.Numerics.Big_Numbers.Big_Integers has some other output operations 
> that you could try: 
> 
> function To_String (Arg : Valid_Big_Integer; ...) return String; 
> 
> procedure Put_Image (Buffer : ... ; Arg: in Valid_Big_Integer); 
> 
> Of course those might be internally linked to the 'Image function and 
> have the same possible limitation.

Not 100% sure what modular types are but I did try to do something like the following

subtype VeryBigInteger is Big_Integer range 0 .. 10E10000;

which gave "error: incorrect constraint for this kind of type"

Niklas also gave me an epiphany as the exact error my program gives for the upper limit is

raised STORAGE_ERROR : Ada.Numerics.Big_Numbers.Big_Integers.Bignums.Normalize: big integer limit exceeded

I had thought that since the end of this error said big integer limit exceeded it was a problem with the library, but now I'm starting to think I need to get GNAT to allocated more memory for the program.

^ permalink raw reply	[relevance 10%]

* Re: Ada.Numerics.Big_Numbers.Big_Integer has a limit of 300 digits?
  2021-12-22 17:27  5%   ` Michael Ferguson
  2021-12-22 17:43  6%     ` Ben Bacarisse
@ 2021-12-22 17:48 11%     ` Niklas Holsti
  2021-12-22 18:02 10%       ` Michael Ferguson
  2021-12-22 19:26  6%     ` Mark Lorenzen
                       ` (2 subsequent siblings)
  4 siblings, 1 reply; 200+ results
From: Niklas Holsti @ 2021-12-22 17:48 UTC (permalink / raw)


On 2021-12-22 19:27, Michael Ferguson wrote:
> On Wednesday, December 22, 2021 at 11:02:03 AM UTC-6, Luke A. Guest wrote:
>> On 22/12/2021 05:57, Michael Ferguson wrote:
>>> I just started using the Big_Integer library that is a part of the 202X version of ADA.
>>>
>>> It is repeatedly described as an "arbitrary precision library"
>>> that has user defined implementation.

Surely not "user defined"? Possibly "implementation defined".


>>> I was under the impression that this library would be able to
>>> infinitely calculate numbers of any length,

I have the same impression (up to Storage_Error, of course).


>> but there is clearly a default limit of 300 digits.
>> What are you doing that requires that number of digits?
> 
> I am working on ProjectEuler.net problem number 48.
> 
> The questions asks you to sum the numbers n^n for (2 <= n <= 1000)
> and determine what the last ten digits of this number are.
> 
> Obviously, this is quite a trivial problem when using any arbitrary
> precision library.
> 
> I had incorrectly determined that 700^700 had 300 digits, in fact
> 700^700 = 3.7E1991.
> 
> However, my code strictly breaks when the loop range is set to 683,
> which 683^683 = 8.12E1935.


How does it break? Some exception, or something else?

Mark Lorenzen suggested in an earlier post that the limit might be in 
the Big_Integer'Image function. The package 
Ada.Numerics.Big_Numbers.Big_Integers has some other output operations 
that you could try:

    function To_String (Arg : Valid_Big_Integer; ...) return String;

    procedure Put_Image (Buffer : ... ; Arg: in Valid_Big_Integer);

Of course those might be internally linked to the 'Image function and 
have the same possible limitation.

^ permalink raw reply	[relevance 11%]

* Re: Ada.Numerics.Big_Numbers.Big_Integer has a limit of 300 digits?
  2021-12-22 17:27  5%   ` Michael Ferguson
@ 2021-12-22 17:43  6%     ` Ben Bacarisse
  2021-12-22 17:48 11%     ` Niklas Holsti
                       ` (3 subsequent siblings)
  4 siblings, 0 replies; 200+ results
From: Ben Bacarisse @ 2021-12-22 17:43 UTC (permalink / raw)


Michael Ferguson <michaelblakeferguson@gmail.com> writes:

> On Wednesday, December 22, 2021 at 11:02:03 AM UTC-6, Luke A. Guest wrote:
>> On 22/12/2021 05:57, Michael Ferguson wrote: 
>> > I just started using the Big_Integer library that is a part of the 202X version of ADA. 
>> > 
>> > It is repeatedly described as an "arbitrary precision library" that has user defined implementation. 
>> > 
>> > I was under the impression that this library would be able to
>> > infinitely calculate numbers of any length, but there is clearly a
>> > default limit of 300 digits.
>>
>> What are you doing that requires that number of digits?
>
> I am working on ProjectEuler.net problem number 48.
>
> The questions asks you to sum the numbers n^n for (2 <= n <= 1000) and
> determine what the last ten digits of this number are.
>
> Obviously, this is quite a trivial problem when using any arbitrary
> precision library.

Does Ada's Big_Integer type work with modular ranged types?

-- 
Ben.

^ permalink raw reply	[relevance 6%]

* Re: Ada.Numerics.Big_Numbers.Big_Integer has a limit of 300 digits?
  2021-12-22 16:04  6%   ` AdaMagica
@ 2021-12-22 17:37  5%     ` Niklas Holsti
  0 siblings, 0 replies; 200+ results
From: Niklas Holsti @ 2021-12-22 17:37 UTC (permalink / raw)


On 2021-12-22 18:04, AdaMagica wrote:
>> Bignum_Limit : constant := 200;
> RM 2.2(14) limiits the line length and the length of lexical elements to 200.


To express it more clearly, RM 2.2(14) requires implementations to 
support lines and lexical elements of /at least/ 200 characters, but 
/allows/ implementations to support longer lines and lexical elements.

I'm not sure if GNAT supports more than 200 characters, though. And of 
course an Ada program that uses more than 200 characters may not be 
portable to compilers that support only 200.

But I don't see any direct logical connection to the number of digits 
that Big_Integers can support. While one cannot write a big-number 
literal longer than a line or longer than the maximum length of a 
lexical element, that should not directly limit the size of big-number 
values in computations.

^ permalink raw reply	[relevance 5%]

* Re: Ada.Numerics.Big_Numbers.Big_Integer has a limit of 300 digits?
  2021-12-22 17:01  6% ` Luke A. Guest
@ 2021-12-22 17:27  5%   ` Michael Ferguson
  2021-12-22 17:43  6%     ` Ben Bacarisse
                       ` (4 more replies)
  0 siblings, 5 replies; 200+ results
From: Michael Ferguson @ 2021-12-22 17:27 UTC (permalink / raw)


On Wednesday, December 22, 2021 at 11:02:03 AM UTC-6, Luke A. Guest wrote:
> On 22/12/2021 05:57, Michael Ferguson wrote: 
> > I just started using the Big_Integer library that is a part of the 202X version of ADA. 
> > 
> > It is repeatedly described as an "arbitrary precision library" that has user defined implementation. 
> > 
> > I was under the impression that this library would be able to infinitely calculate numbers of any length, but there is clearly a default limit of 300 digits.
> What are you doing that requires that number of digits?

I am working on ProjectEuler.net problem number 48.

The questions asks you to sum the numbers n^n for (2 <= n <= 1000) and determine what the last ten digits of this number are.

Obviously, this is quite a trivial problem when using any arbitrary precision library.

I had incorrectly determined that 700^700 had 300 digits, in fact 700^700 = 3.7E1991.

However, my code strictly breaks when the loop range is set to 683, which 683^683 = 8.12E1935.

So, that is interesting that the Big_Integer type works numbers of just under 2000 digit length despite Bignum_Limit : constant := 200.

^ permalink raw reply	[relevance 5%]

* Re: Ada.Numerics.Big_Numbers.Big_Integer has a limit of 300 digits?
  2021-12-22  5:57 11% Ada.Numerics.Big_Numbers.Big_Integer has a limit of 300 digits? Michael Ferguson
  2021-12-22  8:25  6% ` Mark Lorenzen
  2021-12-22 11:14  6% ` AdaMagica
@ 2021-12-22 17:01  6% ` Luke A. Guest
  2021-12-22 17:27  5%   ` Michael Ferguson
  2021-12-23 15:48  6% ` Jeffrey R.Carter
  3 siblings, 1 reply; 200+ results
From: Luke A. Guest @ 2021-12-22 17:01 UTC (permalink / raw)


On 22/12/2021 05:57, Michael Ferguson wrote:
> I just started using the Big_Integer library that is a part of the 202X version of ADA.
> 
> It is repeatedly described as an "arbitrary precision library" that has user defined implementation.
> 
> I was under the impression that this library would be able to infinitely calculate numbers of any length, but there is clearly a default limit of 300 digits.

What are you doing that requires that number of digits?

^ permalink raw reply	[relevance 6%]

* Re: Ada.Numerics.Big_Numbers.Big_Integer has a limit of 300 digits?
  2021-12-22 11:14  6% ` AdaMagica
  2021-12-22 11:32  6%   ` AdaMagica
@ 2021-12-22 16:04  6%   ` AdaMagica
  2021-12-22 17:37  5%     ` Niklas Holsti
  2021-12-22 20:34  6%   ` Simon Wright
  2 siblings, 1 reply; 200+ results
From: AdaMagica @ 2021-12-22 16:04 UTC (permalink / raw)


> Bignum_Limit : constant := 200; 
RM 2.2(14) limiits the line length and the length of lexical elements to 200.

^ permalink raw reply	[relevance 6%]

* Re: Ada.Numerics.Big_Numbers.Big_Integer has a limit of 300 digits?
  2021-12-22 11:14  6% ` AdaMagica
@ 2021-12-22 11:32  6%   ` AdaMagica
  2021-12-22 16:04  6%   ` AdaMagica
  2021-12-22 20:34  6%   ` Simon Wright
  2 siblings, 0 replies; 200+ results
From: AdaMagica @ 2021-12-22 11:32 UTC (permalink / raw)


See RM 1.1.3(2).
I guess this limit is just a transient arbitrary limit until Ada 2022 is standardized.

^ permalink raw reply	[relevance 6%]

* Re: Ada.Numerics.Big_Numbers.Big_Integer has a limit of 300 digits?
  2021-12-22  5:57 11% Ada.Numerics.Big_Numbers.Big_Integer has a limit of 300 digits? Michael Ferguson
  2021-12-22  8:25  6% ` Mark Lorenzen
@ 2021-12-22 11:14  6% ` AdaMagica
  2021-12-22 11:32  6%   ` AdaMagica
                     ` (2 more replies)
  2021-12-22 17:01  6% ` Luke A. Guest
  2021-12-23 15:48  6% ` Jeffrey R.Carter
  3 siblings, 3 replies; 200+ results
From: AdaMagica @ 2021-12-22 11:14 UTC (permalink / raw)


There is a limit
Bignum_Limit : constant := 200;
in System.Generic_Bignums body, function Normalize, lines 1100ff.

I do not see an implementation advice, implementation permission or implementation requirement about such limits in A.5.5, A.5.6.

But there is somewhere in the RM a paragraph stating that implementation may pose limits on certain features. I just cannot find the place in the RM.

^ permalink raw reply	[relevance 6%]

* Re: Ada.Numerics.Big_Numbers.Big_Integer has a limit of 300 digits?
  2021-12-22  5:57 11% Ada.Numerics.Big_Numbers.Big_Integer has a limit of 300 digits? Michael Ferguson
@ 2021-12-22  8:25  6% ` Mark Lorenzen
  2021-12-22 11:14  6% ` AdaMagica
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 200+ results
From: Mark Lorenzen @ 2021-12-22  8:25 UTC (permalink / raw)


On Wednesday, December 22, 2021 at 6:57:10 AM UTC+1, Michael Ferguson wrote:
> I just started using the Big_Integer library that is a part of the 202X version of ADA. 
> 
> It is repeatedly described as an "arbitrary precision library" that has user defined implementation. 
> 
> I was under the impression that this library would be able to infinitely calculate numbers of any length, but there is clearly a default limit of 300 digits. 
> 
How did you determine the limit of 300 digits? I see nothing in your example, that would imply such a limit. Are you sure that you are not reaching a line length limit in Text_IO or maybe a limit in the Image attribute?

Regards,
Mark L

^ permalink raw reply	[relevance 6%]

* Ada.Numerics.Big_Numbers.Big_Integer has a limit of 300 digits?
@ 2021-12-22  5:57 11% Michael Ferguson
  2021-12-22  8:25  6% ` Mark Lorenzen
                   ` (3 more replies)
  0 siblings, 4 replies; 200+ results
From: Michael Ferguson @ 2021-12-22  5:57 UTC (permalink / raw)


I just started using the Big_Integer library that is a part of the 202X version of ADA.

It is repeatedly described as an "arbitrary precision library" that has user defined implementation.

I was under the impression that this library would be able to infinitely calculate numbers of any length, but there is clearly a default limit of 300 digits.

Is there any way to get rid of this problem?

Here is some example code:

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Real_Time; use Ada.Real_Time;
with Ada.Numerics.Big_Numbers.Big_Integers;
use Ada.Numerics.Big_Numbers.Big_Integers;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;

procedure Test is
package Time_IO is new Fixed_IO(Duration);
start_time, end_time : Ada.Real_Time.Time;
elapsed_seconds : Ada.Real_Time.Time_Span;
solution : Unbounded_String;

rop : Big_Integer;
sum : Big_Integer := 0;

begin
start_time := Ada.Real_Time.Clock;

for i in 1..700 loop
rop := To_Big_Integer(i) ** Natural(i);
sum := sum + rop;
end loop;
solution := To_Unbounded_String(sum'Image);


end_time := Ada.Real_Time.Clock;
elapsed_seconds := end_time - start_time;
Put("Solution: " & solution'Image); New_Line; New_Line;
Put("Program completed in ");
Time_IO.Put(To_Duration(elapsed_seconds), Fore => 0, Aft => 3);
Put(" seconds");
end BigTest;

^ permalink raw reply	[relevance 11%]

* Re: Gnat bug or mistaken program?
  2021-07-27 16:00  0%       ` Niklas Holsti
@ 2021-07-28  5:21  0%         ` J-P. Rosen
  0 siblings, 0 replies; 200+ results
From: J-P. Rosen @ 2021-07-28  5:21 UTC (permalink / raw)


Le 27/07/2021 à 18:00, Niklas Holsti a écrit :
>> * Rename the operation:
>>    function "**" (Left : Float; Right : Float) return Float renames
>>       Ada.Numerics.Elementary_Functions."**";
>>    This makes the specific operation visible
> 
> 
> Before Ada got "use type", such renaming declarations were the only 
> alternative to "use package", but they are verbose and proved (in my 
> experience, and that of others too) to be very error-prone, mainly when 
> renaming many operators -- copy-paste errors were rampant and hard to 
> find by reading. Interesting effects occur when "-" is renamed as "+" or 
> vice versa. I consider this solution to be the last (worst) choice.

With AdaControl, you can check that operators that are renamed as a 
different operator:
    check renaming_declarations
       (not identical operator as_operator function);

(This syntax is from the soon-to-be-released new version of AdaControl - 
wavefront available from GitHub: github.adalog.fr)

-- 
J-P. Rosen
Adalog
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52
https://www.adalog.fr

^ permalink raw reply	[relevance 0%]

* Re: Gnat bug or mistaken program?
  2021-07-21  8:29  5%     ` Jeffrey R. Carter
  2021-07-21 16:56  0%       ` Shark8
@ 2021-07-27 16:00  0%       ` Niklas Holsti
  2021-07-28  5:21  0%         ` J-P. Rosen
  1 sibling, 1 reply; 200+ results
From: Niklas Holsti @ 2021-07-27 16:00 UTC (permalink / raw)


I disagree with Jeffrey's opinion on what is a reasonable solution here. 
More in-line below.


On 2021-07-21 11:29, Jeffrey R. Carter wrote:
> On 7/21/21 4:23 AM, Richard Iswara wrote:
>> On 20/07/2021 21.09, Niklas Holsti wrote:
>>> On 2021-07-20 15:02, Richard Iswara wrote:
>>>> I get this error on my program from the menu build => check semantic
>>>> exponent must be of type Natural, found type "Standard.Float".
>>>>
>>>> Should not 10 ** (log10 a + log10 b) = a*b?
>>>>
>>>> This is my compiler build:
>>>>
>>>> GNAT Studio Community 2020 (20200427) hosted on x86_64-pc-mingw32
>>>> GNAT Community 2020 (20200429-93) targetting x86_64-pc-mingw32
>>>> SPARK Community 2020 (20200429)
>>>>
>>>> Here is the relevant part of program:
>>>>
>>>> with Ada.Numerics.Elementary_Functions;
>>>> use Ada.Numerics;
>>>
>>>
>>> To make Ada.Numerics.Elementary_Functions."**" visible without 
>>> qualification, you should also do "use 
>>> Ada.Numerics.Elementary_Functions".
>>>
>>> Otherwise the compiler will see only the predefined operator:
>>>
>>>     function "**"(Left : Float; Right : Integer'Base) return Float
>>>
>>> (see RM 4.5.6(9 and 10)) which explains why the compiler does not 
>>> accept a floating-point value as the Right operand to "**".
>>>
>>>
>>>> Logs : Float := 0.0;
>>>> Multiples : Float;
>>>     ...> Multiples := 10.0 ** Logs;  => this is where it fails
>>>
>>>
>>> It fails because the compiler sees only the predefined "**" operator 
>>> which has an integral right operand.
>>
>> Thank you. So it is a visibility problem.
> 
> "Understanding visibility is the key to understanding Ada." -- /Ada 
> Distilled/


Hm. I agree visibility is important, but it is hardly the only important 
Ada concept.


> Recommending the use package clause as a solution to a misunderstanding 
> of visibility is a disservice to a beginning user.


Yes, unless the recommendation also includes explaining what the "use 
package" does, thus increasing the user's understanding of visibility.


> In decreasing order of specificity, the ways to call an operation in a 
> pkg are
> 
> * Use the full name: Ada.Numerics.Elementary_Functions."**" (10.0, Logs)
>    This calls the operation once without changing its visibility


An application that needs "**" is likely to need other operators. Using 
the fully qualified names makes non-trivial expressions much harder to 
read and write. In the special case of a very few uses of very few 
operators, I agree that this is a workable solution.


> * Rename the operation:
>    function "**" (Left : Float; Right : Float) return Float renames
>       Ada.Numerics.Elementary_Functions."**";
>    This makes the specific operation visible


Before Ada got "use type", such renaming declarations were the only 
alternative to "use package", but they are verbose and proved (in my 
experience, and that of others too) to be very error-prone, mainly when 
renaming many operators -- copy-paste errors were rampant and hard to 
find by reading. Interesting effects occur when "-" is renamed as "+" or 
vice versa. I consider this solution to be the last (worst) choice.


> * Use type: this makes all operators of the type visible (not applicable
>    in this case)
> * Use all type: this makes all operations of the type visible (not
>    applicable in this case)


These are IMO usually the best methods but, as you say, not applicable here.


> * Use package: this makes everything in the package visible
> 
> Use pkg is clearly overkill for this case,


I disagree. If the code uses several operators from the package, a "use 
package" is apt (because "use type" does not apply here), but should of 
course be as local as possible.


> and overuse of it can have negative consequences.


Agreed.

^ permalink raw reply	[relevance 0%]

* Re: Gnat bug or mistaken program?
  2021-07-21 16:56  0%       ` Shark8
@ 2021-07-22  2:14  0%         ` Richard Iswara
  0 siblings, 0 replies; 200+ results
From: Richard Iswara @ 2021-07-22  2:14 UTC (permalink / raw)


On 21/07/2021 23.56, Shark8 wrote:
> On Wednesday, July 21, 2021 at 2:29:22 AM UTC-6, Jeffrey R. Carter wrote:
>>> Thank you. So it is a visibility problem.
>> "Understanding visibility is the key to understanding Ada." -- /Ada Distilled/
>>
>> Recommending the use package clause as a solution to a misunderstanding of
>> visibility is a disservice to a beginning user. Widespread application of use
>> pkg clauses is a crutch to avoid understanding visibility. I recommend that
>> those who do not understand visibility avoid the use clause altogether, as this
>> forces them to learn about visibility. When one understands visibility, one can
>> then make reasoned decisions about whether and when to add use clauses.
>>
>> In decreasing order of specificity, the ways to call an operation in a pkg are
>>
>> * Use the full name: Ada.Numerics.Elementary_Functions."**" (10.0, Logs)
>> This calls the operation once without changing its visibility
>> * Rename the operation:
>> function "**" (Left : Float; Right : Float) return Float renames
>> Ada.Numerics.Elementary_Functions."**";
>> This makes the specific operation visible
>> * Use type: this makes all operators of the type visible (not applicable
>> in this case)
>> * Use all type: this makes all operations of the type visible (not
>> applicable in this case)
>> * Use package: this makes everything in the package visible
>>
>> Use pkg is clearly overkill for this case, and overuse of it can have negative
>> consequences.
>>
>> -- 
>> Jeff Carter
>> "Choose a data representation that
>> makes the program simple."
>> Elements of Programming Style
>> 188
> 
> This is excellent advice and an good list, though the last element should be two or three:
> * Local, via declare-region/-scope; and
> * ["local" via usage inside the spec, (perhaps in the public portion, perhaps in the private); and]
> * Global (top of the file context-clauses).
> 

Thank you all for your tips and explanations.

^ permalink raw reply	[relevance 0%]

* Re: Gnat bug or mistaken program?
  2021-07-21  8:29  5%     ` Jeffrey R. Carter
@ 2021-07-21 16:56  0%       ` Shark8
  2021-07-22  2:14  0%         ` Richard Iswara
  2021-07-27 16:00  0%       ` Niklas Holsti
  1 sibling, 1 reply; 200+ results
From: Shark8 @ 2021-07-21 16:56 UTC (permalink / raw)


On Wednesday, July 21, 2021 at 2:29:22 AM UTC-6, Jeffrey R. Carter wrote:
> > Thank you. So it is a visibility problem.
> "Understanding visibility is the key to understanding Ada." -- /Ada Distilled/ 
> 
> Recommending the use package clause as a solution to a misunderstanding of 
> visibility is a disservice to a beginning user. Widespread application of use 
> pkg clauses is a crutch to avoid understanding visibility. I recommend that 
> those who do not understand visibility avoid the use clause altogether, as this 
> forces them to learn about visibility. When one understands visibility, one can 
> then make reasoned decisions about whether and when to add use clauses. 
> 
> In decreasing order of specificity, the ways to call an operation in a pkg are 
> 
> * Use the full name: Ada.Numerics.Elementary_Functions."**" (10.0, Logs) 
> This calls the operation once without changing its visibility 
> * Rename the operation: 
> function "**" (Left : Float; Right : Float) return Float renames 
> Ada.Numerics.Elementary_Functions."**"; 
> This makes the specific operation visible 
> * Use type: this makes all operators of the type visible (not applicable 
> in this case) 
> * Use all type: this makes all operations of the type visible (not 
> applicable in this case) 
> * Use package: this makes everything in the package visible 
> 
> Use pkg is clearly overkill for this case, and overuse of it can have negative 
> consequences. 
> 
> -- 
> Jeff Carter 
> "Choose a data representation that 
> makes the program simple." 
> Elements of Programming Style 
> 188

This is excellent advice and an good list, though the last element should be two or three:
* Local, via declare-region/-scope; and
* ["local" via usage inside the spec, (perhaps in the public portion, perhaps in the private); and]
* Global (top of the file context-clauses).

^ permalink raw reply	[relevance 0%]

* Re: Gnat bug or mistaken program?
  2021-07-21  2:23  0%   ` Richard Iswara
@ 2021-07-21  8:29  5%     ` Jeffrey R. Carter
  2021-07-21 16:56  0%       ` Shark8
  2021-07-27 16:00  0%       ` Niklas Holsti
  0 siblings, 2 replies; 200+ results
From: Jeffrey R. Carter @ 2021-07-21  8:29 UTC (permalink / raw)


On 7/21/21 4:23 AM, Richard Iswara wrote:
> On 20/07/2021 21.09, Niklas Holsti wrote:
>> On 2021-07-20 15:02, Richard Iswara wrote:
>>> I get this error on my program from the menu build => check semantic
>>> exponent must be of type Natural, found type "Standard.Float".
>>>
>>> Should not 10 ** (log10 a + log10 b) = a*b?
>>>
>>> This is my compiler build:
>>>
>>> GNAT Studio Community 2020 (20200427) hosted on x86_64-pc-mingw32
>>> GNAT Community 2020 (20200429-93) targetting x86_64-pc-mingw32
>>> SPARK Community 2020 (20200429)
>>>
>>> Here is the relevant part of program:
>>>
>>> with Ada.Numerics.Elementary_Functions;
>>> use Ada.Numerics;
>>
>>
>> To make Ada.Numerics.Elementary_Functions."**" visible without qualification, 
>> you should also do "use Ada.Numerics.Elementary_Functions".
>>
>> Otherwise the compiler will see only the predefined operator:
>>
>>     function "**"(Left : Float; Right : Integer'Base) return Float
>>
>> (see RM 4.5.6(9 and 10)) which explains why the compiler does not accept a 
>> floating-point value as the Right operand to "**".
>>
>>
>>> Logs : Float := 0.0;
>>> Multiples : Float;
>>     ...> Multiples := 10.0 ** Logs;  => this is where it fails
>>
>>
>> It fails because the compiler sees only the predefined "**" operator which has 
>> an integral right operand.
> 
> Thank you. So it is a visibility problem.

"Understanding visibility is the key to understanding Ada." -- /Ada Distilled/

Recommending the use package clause as a solution to a misunderstanding of 
visibility is a disservice to a beginning user. Widespread application of use 
pkg clauses is a crutch to avoid understanding visibility. I recommend that 
those who do not understand visibility avoid the use clause altogether, as this 
forces them to learn about visibility. When one understands visibility, one can 
then make reasoned decisions about whether and when to add use clauses.

In decreasing order of specificity, the ways to call an operation in a pkg are

* Use the full name: Ada.Numerics.Elementary_Functions."**" (10.0, Logs)
   This calls the operation once without changing its visibility
* Rename the operation:
   function "**" (Left : Float; Right : Float) return Float renames
      Ada.Numerics.Elementary_Functions."**";
   This makes the specific operation visible
* Use type: this makes all operators of the type visible (not applicable
   in this case)
* Use all type: this makes all operations of the type visible (not
   applicable in this case)
* Use package: this makes everything in the package visible

Use pkg is clearly overkill for this case, and overuse of it can have negative 
consequences.

-- 
Jeff Carter
"Choose a data representation that
makes the program simple."
Elements of Programming Style
188

^ permalink raw reply	[relevance 5%]

* Re: Gnat bug or mistaken program?
  2021-07-20 14:09  6% ` Niklas Holsti
@ 2021-07-21  2:23  0%   ` Richard Iswara
  2021-07-21  8:29  5%     ` Jeffrey R. Carter
  0 siblings, 1 reply; 200+ results
From: Richard Iswara @ 2021-07-21  2:23 UTC (permalink / raw)


On 20/07/2021 21.09, Niklas Holsti wrote:
> On 2021-07-20 15:02, Richard Iswara wrote:
>> I get this error on my program from the menu build => check semantic
>> exponent must be of type Natural, found type "Standard.Float".
>>
>> Should not 10 ** (log10 a + log10 b) = a*b?
>>
>> This is my compiler build:
>>
>> GNAT Studio Community 2020 (20200427) hosted on x86_64-pc-mingw32
>> GNAT Community 2020 (20200429-93) targetting x86_64-pc-mingw32
>> SPARK Community 2020 (20200429)
>>
>> Here is the relevant part of program:
>>
>> with Ada.Numerics.Elementary_Functions;
>> use Ada.Numerics;
> 
> 
> To make Ada.Numerics.Elementary_Functions."**" visible without 
> qualification, you should also do "use Ada.Numerics.Elementary_Functions".
> 
> Otherwise the compiler will see only the predefined operator:
> 
>     function "**"(Left : Float; Right : Integer'Base) return Float
> 
> (see RM 4.5.6(9 and 10)) which explains why the compiler does not accept 
> a floating-point value as the Right operand to "**".
> 
> 
>> Logs : Float := 0.0;
>> Multiples : Float;
>     ...> Multiples := 10.0 ** Logs;  => this is where it fails
> 
> 
> It fails because the compiler sees only the predefined "**" operator 
> which has an integral right operand.

Thank you. So it is a visibility problem.

^ permalink raw reply	[relevance 0%]

* Re: Gnat bug or mistaken program?
  2021-07-20 12:02  7% Gnat bug or mistaken program? Richard Iswara
@ 2021-07-20 14:09  6% ` Niklas Holsti
  2021-07-21  2:23  0%   ` Richard Iswara
  0 siblings, 1 reply; 200+ results
From: Niklas Holsti @ 2021-07-20 14:09 UTC (permalink / raw)


On 2021-07-20 15:02, Richard Iswara wrote:
> I get this error on my program from the menu build => check semantic
> exponent must be of type Natural, found type "Standard.Float".
> 
> Should not 10 ** (log10 a + log10 b) = a*b?
> 
> This is my compiler build:
> 
> GNAT Studio Community 2020 (20200427) hosted on x86_64-pc-mingw32
> GNAT Community 2020 (20200429-93) targetting x86_64-pc-mingw32
> SPARK Community 2020 (20200429)
> 
> Here is the relevant part of program:
> 
> with Ada.Numerics.Elementary_Functions;
> use Ada.Numerics;


To make Ada.Numerics.Elementary_Functions."**" visible without 
qualification, you should also do "use Ada.Numerics.Elementary_Functions".

Otherwise the compiler will see only the predefined operator:

    function "**"(Left : Float; Right : Integer'Base) return Float

(see RM 4.5.6(9 and 10)) which explains why the compiler does not accept 
a floating-point value as the Right operand to "**".


> Logs : Float := 0.0;
> Multiples : Float;
    ...> Multiples := 10.0 ** Logs;  => this is where it fails


It fails because the compiler sees only the predefined "**" operator 
which has an integral right operand.

^ permalink raw reply	[relevance 6%]

* Gnat bug or mistaken program?
@ 2021-07-20 12:02  7% Richard Iswara
  2021-07-20 14:09  6% ` Niklas Holsti
  0 siblings, 1 reply; 200+ results
From: Richard Iswara @ 2021-07-20 12:02 UTC (permalink / raw)


I get this error on my program from the menu build => check semantic
exponent must be of type Natural, found type "Standard.Float".

Should not 10 ** (log10 a + log10 b) = a*b?

This is my compiler build:

GNAT Studio Community 2020 (20200427) hosted on x86_64-pc-mingw32
GNAT Community 2020 (20200429-93) targetting x86_64-pc-mingw32
SPARK Community 2020 (20200429)

Here is the relevant part of program:

with Ada.Numerics.Elementary_Functions;  
use Ada.Numerics;

Counter : Integer := 1;
Logs : Float := 0.0;
Multiples : Float;

inside some loop:

Logs := Elementary_Functions.Log (Float(Counter), 10.0) + Logs;
Multiples := 10.0 ** Logs;  => this is where it fails

I checked the Ada.Numerics.Generic_Elementary_Functions specifications
(since Ada.Numerics.Elementary_Functions is just an instance of the generics)
and it said:

   function "**" (Left, Right : Float_Type'Base) return Float_Type'Base with
     Pre  => (if Left = 0.0 then Right > 0.0) and Left >= 0.0,
     Post => "**"'Result >= 0.0
       and then (if Right = 0.0 then "**"'Result = 1.0)
       and then (if Right = 1.0 then "**"'Result = Left)
       and then (if Left  = 1.0 then "**"'Result = 1.0)
       and then (if Left  = 0.0 then "**"'Result = 0.0);

So the question is this a Gnat bug, wrong function used, faulty logic on me or
I am declaring it wrong?

^ permalink raw reply	[relevance 7%]

* Re: Constraint error overflow
  @ 2021-04-27 16:31  6%     ` Simon Wright
  0 siblings, 0 replies; 200+ results
From: Simon Wright @ 2021-04-27 16:31 UTC (permalink / raw)


Richard Iswara <haujekchifan@gmail.com> writes:

> So the compiler is restricted to 32 bit integer value. I had hoped for
> 64 bit to get 18 digits.

GNAT comes with Long_Integer (64 bits).

Or yu could go with the Ada202x Big_Integers package
(http://www.ada-auth.org/standards/2xrm/html/RM-A-5-6.html),

pragma Ada_2020;

with Ada.Text_IO;
with Ada.Numerics.Big_Numbers.Big_Integers;

procedure Iswara is

   use Ada.Numerics.Big_Numbers.Big_Integers;

   Sum : Big_Natural := 0;
   Mul : Big_Natural := 1;

begin
   Ada.Text_IO.Put ( "Sum of the first 100 integers is :" );
   Ada.Text_IO.New_Line;
   Summing:
   for I in 1 .. 100 loop
      Sum := Sum + To_Big_Integer (I);
   end loop Summing;
   Ada.Text_IO.Put ( Sum'Image );
   Ada.Text_IO.New_Line;

   Ada.Text_IO.Put ( "Multiple of the first 100 integers is :" );
   Ada.Text_IO.New_Line;
   Multiplying:
   for J in 1 .. 100 loop
      Mul := Mul * To_Big_Integer (J);
   end loop Multiplying;
   Ada.Text_IO.Put ( Mul'Image );
   Ada.Text_IO.New_Line;
end Iswara;

which compiles fine with GNAT CE 2020 & FSF GCC 11.0.1; result

$ ./iswara 
Sum of the first 100 integers is :
 5050
Multiple of the first 100 integers is :
 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000

^ permalink raw reply	[relevance 6%]

* Re: Compiler stuck on Big_Integer array initialisation
  2021-03-14  1:32  6% Compiler stuck on Big_Integer array initialisation Jesper Quorning
@ 2021-04-23  6:37  0% ` Simon Wright
  0 siblings, 0 replies; 200+ results
From: Simon Wright @ 2021-04-23  6:37 UTC (permalink / raw)


Jesper Quorning <jesper.quorning@gmail.com> writes:

> CE2020 GNAT on macOS gets stuck on the following code:
>
> with Ada.Numerics.Big_Numbers.Big_Integers;
> use Ada.Numerics.Big_Numbers.Big_Integers;
> procedure Stuck is
>    A : array (0 .. 9) of Big_Integer := (others => 0);   -- Stuck
> begin
>    null;
> end Stuck;
>
> $ gnatmake -gnat2020 stuck.adb
>
> The array initialisation (others =>0) is the problem. When I changed
> it to (0 => 0, others => 0) it compiles.

FSF GCC 11.0.1 20210331 crashes (internal compiler error).

Both this and GNAT CE 2020 are OK with (others => Big_Integer'(0)).

^ permalink raw reply	[relevance 0%]

* Compiler stuck on Big_Integer array initialisation
@ 2021-03-14  1:32  6% Jesper Quorning
  2021-04-23  6:37  0% ` Simon Wright
  0 siblings, 1 reply; 200+ results
From: Jesper Quorning @ 2021-03-14  1:32 UTC (permalink / raw)


Hi All

CE2020 GNAT on macOS gets stuck on the following code:

with Ada.Numerics.Big_Numbers.Big_Integers;
use Ada.Numerics.Big_Numbers.Big_Integers;
procedure Stuck is
   A : array (0 .. 9) of Big_Integer := (others => 0);   -- Stuck
begin
   null;
end Stuck;

$ gnatmake -gnat2020 stuck.adb

The array initialisation (others =>0) is the problem. When I changed it to (0 => 0, others => 0) it compiles.

Is the problem reproducable on Linux and Windows compilers?

/Jesper

^ permalink raw reply	[relevance 6%]

* Re: Advent of Code
  @ 2020-12-13 21:36  5%                     ` John Perry
  0 siblings, 0 replies; 200+ results
From: John Perry @ 2020-12-13 21:36 UTC (permalink / raw)


On Sunday, December 13, 2020 at 12:26:37 PM UTC-6, Maxim Reznik wrote:
> Day 13 Part II was hard to me :( And result works only on GCC 11, where we will have 128 bits integers support at last. 
> 
> https://github.com/reznikmm/ada-howto/blob/advent-2020/md/13/13.md 

I got around that using Ada.Numerics.Big_Numbers.Big_Integers. GNAT reports version 20200429-84.

(At first I used System.Bignum because I couldn't figure out how to make Big_Integers work, but somehow I cracked the package naming system... ;-) )

^ permalink raw reply	[relevance 5%]

* Re: advent of code day 10
  @ 2020-12-11 17:04  5%   ` Stephen Leake
  0 siblings, 0 replies; 200+ results
From: Stephen Leake @ 2020-12-11 17:04 UTC (permalink / raw)


Jared Summers <jtsummers@gmail.com> writes:

> On Thursday, December 10, 2020 at 8:39:36 PM UTC-7, Stephen Leake wrote:
>> I cheated; the final total is larger than 64 bits, so I just printed out 
>> the factors and used Emacs built-in bignums to compute it. I assume 
>> there is an Ada bignums package out there, and the compiler has one that 
>> full Ada 2020 will expose, but I'm trying to catch up, so did not look. 
>
> My answer was able to fit in a Long_Long_Integer on my machine. But,
> due to a bug, I did play with the Big_Integers package. It worked
> well, and I'd recommend taking a look at it for upcoming problems.

Yes; GNAT Community 2020 with -gnat2020 and -gnatX supports
Ada.Numerics.Big_Integer. I updated my solution to use that.

-- 
-- Stephe

^ permalink raw reply	[relevance 5%]

* Re: GNAT vs Matlab - operation on   multidimensional complex matrices
  2020-03-23 23:16  5% GNAT vs Matlab - operation on multidimensional complex matrices darek
@ 2020-06-08 17:42  6% ` Shark8
  0 siblings, 0 replies; 200+ results
From: Shark8 @ 2020-06-08 17:42 UTC (permalink / raw)


Cleaning out my computer, I found this working-file; it might be of interesti to you -- it shows "going all-in" with Generics:
--------------------------------------------------------------
With
Ada.Real_Time,
Ada.Containers.Indefinite_Holders,
Ada.Numerics.Long_Complex_Types,
Ada.Exceptions,
Ada.Text_IO.Complex_IO;

Procedure Demo is
    package TIO renames Ada.Text_IO;
    package CTIO is new TIO.Complex_IO(Ada.Numerics.Long_Complex_Types);

    subtype mReal   is Long_Float;
    subtype Complex is Ada.Numerics.Long_Complex_Types.Complex;


    NumIteration : constant  := 1_000;
    NumChannels  : constant  := 64;
    NumRanges    : constant  := 400;
    NumAngles    : constant  := 30;


    Type Channel is range 1..NumChannels;
    Type Angle   is range 1..NumAngles;
    Type Range_T is range 1..NumRanges;

    type tCubeReal    is array (Channel, Angle, Range_T) of mReal;
    type tCubeComplex is array (Channel, Angle, Range_T) of Complex;

    Generic
        Type T is private;
        Type IndexA is (<>);
        Type IndexB is (<>);
        Type IndexC is (<>);
        Type Cubic is Array(IndexA, IndexB, indexC) of T;
        Zero : in T;
        with Function "+"(Left, Right: T) return T is <>;
    Function Summation( Input : Cubic ) return T
      with Inline;

    Function Summation( Input : Cubic ) return T is
    Begin
        Return Result : T := Zero do
            For A in IndexA loop
                For B in IndexB loop
                    For C in IndexC loop
                        Result:= Result + Input(A, B, C);
                    End loop;
                End loop;
            End loop;
        End return;
    End Summation;

    Generic
        Type Element is private;
        Type Cubic is array (Channel, Angle, Range_T) of Element;
        Zero : In Element;
        with Function "+"(Left, Right: Element) return Element is <>;
    Procedure Timing_Harness(Mtx : in Cubic;  S: out Element; Iterations : in Positive:= 1);

    Procedure Timing_Harness(Mtx : in Cubic;  S: out Element; Iterations : in Positive:= 1) is
        Function Sum is new Summation(Element, Channel, Angle, Range_T, Cubic, Zero);
        Use Ada.Real_Time;
        Start : Time renames Clock;
    Begin
        For Count in 1..Iterations Loop
            S := Sum( Mtx );
        End loop;


        METRICS:
        Declare
            Execution_Time  : Constant Time_Span:= Clock - Start;
            Execution_Image : Constant String:= Duration'Image(To_Duration(Execution_Time));
            T : Constant mReal := mReal(To_Duration(Execution_Time))/mReal(NumIteration);
        Begin
            TIO.New_Line;
            TIO.Put_Line("Computation time:" & Execution_Image );
            TIO.Put_Line("Computation time per iteration:" & mReal'Image(T));
        End METRICS;
    End Timing_Harness;


    Function Image( Input : mReal   )  return string renames mReal'Image;
    Function Image( Input : Complex )  return string is
        ('(' & mReal'Image(Input.Re) & ", " & mReal'Image(Input.Im) & ')');
    
    Generic
        Type T is private;
        Type IndexA is (<>);
        Type IndexB is (<>);
        Type IndexC is (<>);
        Type Cubic is Array(IndexA, IndexB, indexC) of T;
        Default : in T;
    Package Test_Data is
        Type Access_Cubic is not null access all Cubic;

        Access_Data : Constant Access_Cubic := new Cubic'(others => (others => (others => Default)));
        Data        : Cubic renames Access_Data.all;
    End Test_Data;

    Generic
        Type Element    is private;
        Type Cube_Array is array (Channel, Angle, Range_T) of Element;
        Default,
        Zero      : in Element;
        Test_Name : in String;
        with Function "+"(Left, Right: Element) return Element is <>;
        with Function Image( Input : Element )  return string  is <>;
    Procedure TEST;


    Procedure TEST is

        Package Test_Set is new Test_Data(
           T       => Element,
           IndexA  => Channel,
           IndexB  => Angle,
           IndexC  => Range_T,
           Cubic   => Cube_Array,
           Default => Default
          );
        
        procedure SpeedSum is new Timing_Harness(
           Element => Element,
           Cubic   => Cube_Array,
           Zero    => Zero,
           "+"     => TEST."+"
          );
        
        Cube   : Cube_Array renames Test_Set.Data;
        Result : Element;
    Begin
        TIO.Put_Line(Test_Name & " cube");
        TIO.Put_Line(Test_Name & " type size is:" & Integer'Image(Element'Size));

        SpeedSum(
           Mtx          => Cube,
           S            => Result,
           Iterations   => NumIteration
          );

        TIO.Put_Line("Sum is:" & Image(Result));
    End TEST;

Begin
    REAL_CUBE_TEST:
    Declare
        Procedure Do_Test is new Test(
           Element    => mReal,
           Cube_Array => tCubeReal,
           Default    => 1.0,
           Zero       => 0.0,
           Test_Name  => "Real"
          );
    Begin
        Do_Test;
    End REAL_CUBE_TEST;

    TIO.Put_Line( (1..20 => '-') ); -- Separator.

    COMPLEX_CUBE_TEST:
    Declare
        Procedure Do_Test is new Test(
           "+"        => Ada.Numerics.Long_Complex_Types."+",
           Element    => Complex,
           Cube_Array => tCubeComplex,
           Default    => (Re => 1.0, Im => 1.0),
           Zero       => (Re => 0.0, Im => 0.0),
           Test_Name  => "Complex"
          );
    Begin
        Do_Test;
    End COMPLEX_CUBE_TEST;



    TIO.Put_Line( (1..20 => '-') ); -- Separator.


    Ada.Text_IO.Put_Line( "Done." );
End Demo;

^ permalink raw reply	[relevance 6%]

* Re: Any good package for mathematical function in Ada?
  @ 2020-06-06 13:58  7%               ` AdaMagica
  0 siblings, 0 replies; 200+ results
From: AdaMagica @ 2020-06-06 13:58 UTC (permalink / raw)


Am Samstag, 6. Juni 2020 09:06:57 UTC+2 schrieb Dmitry A. Kazakov:
> No, it is the type system. Randy posted links to the drafts for 
> unbounded integer and real. Same story. They are not numbers. As a 
> consequence you have no conversions to/from legal numeric types, you 
> need to instantiate generics. They do not match formal numeric types in 
> generics. They have no attributes (some of which would have no sense 
> anyway).

GNAT CE 2020 has them (albeit not in the latest RM form). They behave much like numbers.

pragma Warnings (Off);
with Ada.Numerics.Big_Numbers.Big_Integers, Ada.Numerics.Big_Numbers.Big_Reals;
use  Ada.Numerics.Big_Numbers.Big_Integers, Ada.Numerics.Big_Numbers.Big_Reals;
pragma Warnings (On);

with Ada.Text_IO;
use  Ada.Text_IO;

procedure Main is

  I: Big_Integer := From_String ("   42   ");
  J: Big_Integer := 42;
  R: Big_Real := From_String("10.0")**100 - 1.0;
  S: Big_Real := 10.0**100 - 1/1;
  D: Big_Real := 1 / 3;

begin

  Put_Line (Boolean'(I=J)'Image);
  Put_Line (to_String (R));
  Put_Line (Boolean'Image(R=S));
  Put_Line (to_String (Numerator (S)) & to_String (Denominator (S)));
  Put_Line (to_String (D, Aft => 110));
  Put_Line (to_String (Numerator (D)) & to_String (Denominator (D)));

end Main;

^ permalink raw reply	[relevance 7%]

* Re: generic with function procedure
  2020-06-05 14:52  6% ` gautier_niouzes
@ 2020-06-05 15:45  0%   ` Gilbert Gosseyn
  0 siblings, 0 replies; 200+ results
From: Gilbert Gosseyn @ 2020-06-05 15:45 UTC (permalink / raw)


On Friday, June 5, 2020 at 4:52:13 PM UTC+2, gautier...@hotmail.com wrote:
> It depends on how you have defined g1 and h1...
> You may also want to pass Real as a generic parameter to make your "denm" package work for any precision. Perhaps doing so will solve your problem by the way.
> Here is a package from Mathpaqs, as an inspiration.
> 
> with Ada.Numerics.Generic_Real_Arrays;
> 
> generic
>   type Real is digits <>;
>   with package Real_Arrays is new Ada.Numerics.Generic_Real_Arrays (Real);
>   type Integer_Vector is array (Integer range <>) of Integer;
> 
> package Generic_Real_Linear_Equations is
> 
>   use Real_Arrays;
> 
>   function Linear_Equations ( A : Real_Matrix ;
>                               Y : Real_Vector ) return Real_Vector ;
> ...

I used already:
type Real is digits 18;
package Real_Arrays is instantiated with type Real from above.

Please explain: "It depends on how you have defined g1 and h1...". The functions g1 and h1 are defined in the same manner a f1. If I restrict the numer of with-clauses to one, then there is no error-message.

Thank you for your example. I am still studying it and I can see that it uses different methods in seperate programs with usual parameters. However, there are no functions as parameters involved. As in Ada you cannot use  functions as parameters eg in a procedure, the with clause may be used. My problem is still how to use the with clause correctly?

^ permalink raw reply	[relevance 0%]

* Re: generic with function procedure
  @ 2020-06-05 14:52  6% ` gautier_niouzes
  2020-06-05 15:45  0%   ` Gilbert Gosseyn
  0 siblings, 1 reply; 200+ results
From: gautier_niouzes @ 2020-06-05 14:52 UTC (permalink / raw)


It depends on how you have defined g1 and h1...
You may also want to pass Real as a generic parameter to make your "denm" package work for any precision. Perhaps doing so will solve your problem by the way.
Here is a package from Mathpaqs, as an inspiration.

with Ada.Numerics.Generic_Real_Arrays;

generic
  type Real is digits <>;
  with package Real_Arrays is new Ada.Numerics.Generic_Real_Arrays (Real);
  type Integer_Vector is array (Integer range <>) of Integer;

package Generic_Real_Linear_Equations is

  use Real_Arrays;

  function Linear_Equations ( A : Real_Matrix ;
                              Y : Real_Vector ) return Real_Vector ;
...

^ permalink raw reply	[relevance 6%]

* GNAT vs Matlab - operation on   multidimensional complex matrices
@ 2020-03-23 23:16  5% darek
  2020-06-08 17:42  6% ` Shark8
  0 siblings, 1 reply; 200+ results
From: darek @ 2020-03-23 23:16 UTC (permalink / raw)


Hi Everyone, 
 I am working on radar signal processing algorithms that use multidimensional complex arrays. 

To my surprise, the performance of some Matlab functions is much better than compiled Ada code. 

Let's start with a simple problem of computing sum of all elements in a 3D real and complex array. 

The Ada code is as follows:

with Ada.Text_IO;
with Ada.Real_Time; use Ada.Real_Time;
with Ada.Unchecked_Deallocation;

with Ada.Numerics.Long_Complex_Types;  use Ada.Numerics.Long_Complex_Types;

with Ada.Text_IO.Complex_IO;

procedure TestSpeed is
   

   
   package TIO renames Ada.Text_IO;
   
   package CTIO is new Ada.Text_IO.Complex_IO(Ada.Numerics.Long_Complex_Types);
   
   subtype mReal is Long_Float;
   
   
   NumIteration : constant := 1_000;
   NumChannels  : constant  := 64;
   NumRanges    : constant  := 400; 
   NumAngles    : constant  := 30;
   
   type tCubeReal is array (1..NumChannels, 1..NumAngles, 1..NumRanges) of mReal;
   type tCubeRealAcc is access all tCubeReal;
   --for tCubeReal'Alignment use 8;
   
   type tCubeComplex is array (1..NumChannels, 1..NumAngles, 1..NumRanges) of Complex;
   type tCubeComplexAcc is access all tCubeComplex;
   --for tCubeComplex'Alignment use 16;
   
   RealCubeAcc : tCubeRealAcc;
   SReal       : mReal;
   
   ComplexCubeAcc : tCubeComplexAcc;
   SComplex    : Complex;

   
   procedure Free is new Ada.Unchecked_Deallocation(tCubeReal, tCubeRealAcc);
   procedure Free is new Ada.Unchecked_Deallocation(tCubeComplex, tCubeComplexAcc);
   
   --| -------------------------------------------------------------------------
   procedure SpeedSumRealCube (NumIteration : Integer; Mtx : in  tCubeReal;  S: out mReal) is
      
      Ts   : Time;
      TEx  : Time_Span; 
      t    : mReal;
   begin
      Ts := Clock;
      S := 0.0;
      for k in 1..NumIteration loop
         for m  in Mtx'Range(1) loop
            for n in   Mtx'Range(2) loop
               for p in   Mtx'Range(3) loop
                  S := S + Mtx(m, n, p);
               end loop;
            end loop;
         end loop;      
      end loop;

      TEx :=  Clock - Ts;
      TIO.New_Line;
      TIO.Put_Line("Computation time:" & Duration'Image(To_Duration(TEx)));
      t := mReal(To_Duration(TEx))/mReal(NumIteration);
      TIO.Put_Line("Computation time per iteration:" & t'Image);
   end SpeedSumRealCube;
   
   --| -------------------------------------------------------------------------
   
   procedure SpeedSumComplexCube (NumIteration : Integer; Mtx : in  tCubeComplex;  S:  out Complex) is
      
      Ts   : Time;
      TEx  : Time_Span; 
      t    : mReal;
   begin
      Ts := Clock;     
      S := 0.0  + i* 0.0; 
      for k in 1..NumIteration loop
         for m  in Mtx'Range(1) loop
            for n in    Mtx'Range(2) loop
               for p in   Mtx'Range(3) loop
                  S := S + Mtx(m, n, p);
               end loop;
            end loop;
         end loop;      
      end loop;
      TEx :=  Clock - Ts;
      TIO.New_Line;
      TIO.Put_Line("Computation time:" & Duration'Image(To_Duration(TEx)));
      t := mReal(To_Duration(TEx))/mReal(NumIteration);
      TIO.Put_Line("Computation time per iteration:" & t'Image);
   end SpeedSumComplexCube;
   
   --| -------------------------------------------------------------------------
   
begin
   TIO.Put_Line("Real cube");
   TIO.Put_Line("Real type size is:" & Integer(mReal'Size)'Image);
   RealCubeAcc := new tCubeReal;
   RealCubeAcc.all := (others =>(others =>( others => 1.0)));
   SpeedSumRealCube(NumIteration => NumIteration,
                    Mtx           => RealCubeAcc.all,
                    S            => SReal);
   
   TIO.Put_Line("Sum is:" & SReal'Image);
   
   TIO.Put_Line("Complex cube");
   TIO.Put_Line("Complex type size is:" & Integer(Complex'Size)'Image);
   ComplexCubeAcc := new tCubeComplex;
   ComplexCubeAcc.all := (others =>(others =>( others => 1.0 + i * 1.0)));
   SpeedSumComplexCube(NumIteration => NumIteration,
                       Mtx          => ComplexCubeAcc.all,
                       S            => SComplex);
   
   TIO.Put("Sum is:"); CTIO.Put(SComplex);
   Free(ComplexCubeAcc);
   Free(RealCubeAcc);   
end TestSpeed;

1. Compiled with:  gcc version 9.2.0 (tdm64-1) ( and gnat community edition 2019), with the -O2 optimisation level. 
2. CPU: AMD64 Family 23 Model 24 Stepping 1  CPU0      2300           AMD Ryzen 7 3750H with Radeon Vega Mobile Gfx
3. Win10 64bit 


The results of the program execution:

Computation time: 0.616710300
Computation time per iteration: 6.16710300000000E-04
Sum is: 7.68000000000000E+08
Complex cube
Complex type size is: 128

Computation time: 3.707091000
Computation time per iteration: 3.70709100000000E-03
Sum is:( 7.68000000000000E+08, 7.68000000000000E+08)


The executable produced by the gcc provide with the gnat community edition gave very similar results.

More interesting part - the Matlab code.

Matlab version : Matlab 2019b, 64bit

function [] = TestSpeed 

NumIterations = 1000;
NumChannels = 64;  
NumRanges  = 400; 
NumAngles = 30;

%--| real matrix 

ReMtx = ones(NumChannels, NumAngles, NumRanges);

tic
SReal =  ComputeSum(NumIterations, ReMtx);
TExR = toc;%cputime-ts;
fprintf('TExe:%f, sum real=%f\n', TExR, SReal);
%--| complex matrix
CplxMtx = complex(ReMtx, ReMtx);
%ts = cputime;
tic
SCplx = ComputeSum(NumIterations, CplxMtx);
TExC = toc; %cputime - ts;
fprintf('TExe:%f, sum complex= <%f,%f> \n', TExC, real(SCplx), imag(SCplx));
fprintf('Complex operations are %f times slower\n', TExC/TExR);
end % function


function [S] = ComputeSum(NumIterations, Mtx)
 S = 0;
 for i = 1:NumIterations   
    S = S + sum(sum(sum(Mtx)));  
 end % for  
end % function 

The results of the program execution:

TExe:0.260718, sum real=768000000.000000
TExe:0.789778, sum complex= <768000000.000000,768000000.000000> 
Complex operations are 3.029242 times slower


What is wrong with my code ? Is it the Ada compiler doing bad job here?
 
If you look at Matlab code, on average the computation that use complex  addition are ~3 times slower than for the real numbers.

In the case of Ada code, the complex operations are ~ 6 times slower that for the real numbers. 

Did I miss something somewhere ? Any ideas how I can improve the performance of the Ada program (different array layout, magic pragmas, or magic compiler switches) ?

It seems that Matlab is performing really well here ...

Any suggestions are  very welcome.

Regards,
  Darek  







^ permalink raw reply	[relevance 5%]

* Re: The answer to "Can Ada replace FORTRAN for numerical computation?
  @ 2019-07-23  1:35  6% ` Brad Moore
  0 siblings, 0 replies; 200+ results
From: Brad Moore @ 2019-07-23  1:35 UTC (permalink / raw)


On Sunday, July 21, 2019 at 10:38:16 PM UTC-6, Nasser M. Abbasi wrote:
> In 1980 there was a paper titled "Can Ada replace FORTRAN for numerical computation?"
> 
> ACM SIGPLAN Notices
> Volume 16, Number 12, December, 1981
> 
> 
> https://dl.acm.org/citation.cfm?id=954264
> 
> "
> In July 1980, the proposed final form of the Ada programming
> language was released by the U.S. Department of Defense [1]. Even
> though Ada was not designed specifically for general numeric
> scientific computation, nevertheless the question arises to whether
> it is appropriate for this purpose. This question can best
> be answered by consideration of the following question: Is Ada
> a suitable replacement for the programming language FORTRAN? This
> paper discusses those constructs of Ada which are pertinent to the
> matter and are considered defective. It is noted that the array defects
> are exceptionally critical, not providing needed capabilities
> that exist in FORTRAN and have been extensively used for
>   a quarter century."
> 
> I can't find free version of the paper, any one knows of one? but
> there was more discussion on it here:
> 
> https://archive.org/stream/DTIC_ADA139224/DTIC_ADA139224_djvu.txt
> 
> (just search for string "can ada")
> 
> _But_ to answer the question in the title of the paper, and
> after FORTY years, it is clear now that the answer is a
> resounding NO.

If the goal was to have Ada replace Fortran, that was never a realistic goal to begin with, for many reasons. One being that there exists a lot of legacy Fortran code out there, and secondly I cannot think of any cases where language X replaced language Y. There will likely always be supporters existing for language Y, expecially if it better fits a particular niche.

> 
> Too bad, because Ada could have been best language for numerical
> computation due to its strong typing. But its lack of support
> for many things related to linear algebra and such, as discussed
> in the above, Ada could not replace Fortran.

That being said, a lot has happenned to Ada since Ada 83, when those articles were written, including support for things like linear algebra and such. See Ada.Numerics.Generic_Real_Arrays and Ada.Numerics. Ada.Numerics.Generic_Complex_Arrays, which include routes to Solve matrices, and perform various other operations on them.

e.g.

    --  Real_Matrix inversion and related operations

   function Solve (A : Real_Matrix; X : Real_Vector) return Real_Vector;
   function Solve (A, X : Real_Matrix) return Real_Matrix;
   function Inverse (A : Real_Matrix) return Real_Matrix;
   function Determinant (A : Real_Matrix) return Real'Base;

Brad

^ permalink raw reply	[relevance 6%]

* Re: old problem
  2019-05-30 10:26  7% old problem Gilbert Gosseyn
  2019-05-30 17:08  0% ` Anh Vo
  2019-05-31  1:04  0% ` Keith Thompson
@ 2019-05-31 12:37  7% ` Simon Wright
  2 siblings, 0 replies; 200+ results
From: Simon Wright @ 2019-05-31 12:37 UTC (permalink / raw)


Gilbert Gosseyn <hnptz@yahoo.de> writes:

> How to keep the dimensions Dx,Dy,gK open until execution?

You could make allx a generic, as in the following. I used gnatpp &
adjusted casing; I used 'Range rather than 1 .. Dx etc, but it would
have been possible to make the values visible in the generic
instantiation, e.g.

   Actual_Dx : constant := Dx;

but using the attribute ('Range) is better.

with Ada.Numerics.Generic_Real_Arrays;
generic
   with package Real_Arrays is new Ada.Numerics.Generic_Real_Arrays (<>);
   Dx, Dy, gK : Positive;
package Allx is
   subtype RM is Real_Arrays.Real_Matrix (1 .. Dy, 1 .. Dx);
   type Weight_Array is array (1 .. gK) of RM;
end Allx;

with Ada.Numerics.Generic_Real_Arrays;
with Allx;
with Ada.Text_IO; use Ada.Text_IO;
procedure Testall is
   type Real is digits 18;
   package RIO is new Ada.Text_IO.Float_IO (Real);
   package Real_Arrays is new Ada.Numerics.Generic_Real_Arrays (Real);
   package My_Allx is new Allx (Real_Arrays => Real_Arrays,
                                Dx => 3,
                                Dy => 5,
                                Gk => 3);
   use My_Allx;
   W : Weight_Array;
   D : RM := (others => (others => 1.0));
   procedure Testallx (D1 : RM; W1 : in out Weight_Array) is
      use Real_Arrays;
   begin
      for I in W1'Range loop
         W1 (I) := Real (I) * D1;
      end loop;
   end Testallx;
begin
   Testallx (D, W);
   for K in D'Range (2) loop
      New_Line;
      for I in D'Range (1) loop
         New_Line;
         for J in W'Range loop
            RIO.Put (W (K) (I, J));
         end loop;
      end loop;
      New_Line;
   end loop;
end Testall;

^ permalink raw reply	[relevance 7%]

* Re: old problem
  2019-05-30 10:26  7% old problem Gilbert Gosseyn
  2019-05-30 17:08  0% ` Anh Vo
@ 2019-05-31  1:04  0% ` Keith Thompson
  2019-05-31 12:37  7% ` Simon Wright
  2 siblings, 0 replies; 200+ results
From: Keith Thompson @ 2019-05-31  1:04 UTC (permalink / raw)


Gilbert Gosseyn <hnptz@yahoo.de> writes:
> with Ada.Numerics; use Ada.Numerics;
> with Ada.Numerics.Generic_Real_Arrays;
> package allx is
>    type Real is digits 18;
>    package RA is new Ada.Numerics.Generic_Real_Arrays(Real);
>    use RA;
>    Dx,Dy,gK : Positive;
>    subtype RM is Real_Matrix(1..Dy,1..Dx);
>    type weight_array is array(1..gK) of RM;
> end allx;
[...]

Dy and Dx are uninitialized when Real_Matrix is defined.  Their values
will be arbitrary garbage when the declaration of RM is elaborated.
(I'm a bit surprised you didn't get a compile-time warning.)

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Will write code for food.
void Void(void) { Void(); } /* The recursive call of the void */

^ permalink raw reply	[relevance 0%]

* Re: old problem
  2019-05-30 10:26  7% old problem Gilbert Gosseyn
@ 2019-05-30 17:08  0% ` Anh Vo
  2019-05-31  1:04  0% ` Keith Thompson
  2019-05-31 12:37  7% ` Simon Wright
  2 siblings, 0 replies; 200+ results
From: Anh Vo @ 2019-05-30 17:08 UTC (permalink / raw)


On Thursday, May 30, 2019 at 3:26:17 AM UTC-7, Gilbert Gosseyn wrote:
> with Ada.Numerics; use Ada.Numerics;
> with Ada.Numerics.Generic_Real_Arrays;
> package allx is
>    type Real is digits 18;
>    package RA is new Ada.Numerics.Generic_Real_Arrays(Real);
>    use RA;
>    Dx,Dy,gK : Positive;
>    subtype RM is Real_Matrix(1..Dy,1..Dx);
>    type weight_array is array(1..gK) of RM;
> end allx;
> 
> with allx; use allx;
> with Ada.Text_IO;use Ada.Text_IO;
> procedure testall is
>    package RIO is new Float_IO(Real);
>    use RIO;
>    use allx.RA;
>    W : weight_array;
>    D : RM := (others => (others => 1.0));
>    procedure testallx(D1 : RM;
>                       W1 : in out weight_array) is
>    begin
>       for i in 1..gK loop
>          W1(i) := Real(i)*D1;
>       end loop;
>    end testallx;
> 
> begin
>    Dx := 3;
>    Dy := 5;
>    gK := 3;
>    testallx(D,W);
>    for k in 1..Dx loop
>       new_line(2);
>       for i in 1..Dy loop
>          new_line;
>          for j in 1..gK loop
>             RIO.put(W(k)(i,j));
>          end loop;
>       end loop;
>    end loop;
> end testall;
> 
> raised CONSTRAINT_ERROR : testall.adb:13  (W1(i) := ...)  index check failed, and of course if I use numbers in package allx, then W1(i) is known.
> How to keep the dimensions Dx,Dy,gK open until execution?

Lines 7 and 8 will trigger a CONSTRAINT_ERROR warning when this problem is compiled under GNAT. 

Replace 

   subtype RM is Real_Matrix(1..Dy,1..Dx); 
   type weight_array is array(1..gK) of RM; 

with 
   
   Max : constant := 100;  -- can be adjusted
   subtype Index_Range is Positive range 1 .. Max;
   subtype RM is Real_Matrix(Index_Range, Index_Range); 
   type weight_array is array(Index_Range) of RM; 

Anh Vo


^ permalink raw reply	[relevance 0%]

* old problem
@ 2019-05-30 10:26  7% Gilbert Gosseyn
  2019-05-30 17:08  0% ` Anh Vo
                   ` (2 more replies)
  0 siblings, 3 replies; 200+ results
From: Gilbert Gosseyn @ 2019-05-30 10:26 UTC (permalink / raw)


with Ada.Numerics; use Ada.Numerics;
with Ada.Numerics.Generic_Real_Arrays;
package allx is
   type Real is digits 18;
   package RA is new Ada.Numerics.Generic_Real_Arrays(Real);
   use RA;
   Dx,Dy,gK : Positive;
   subtype RM is Real_Matrix(1..Dy,1..Dx);
   type weight_array is array(1..gK) of RM;
end allx;

with allx; use allx;
with Ada.Text_IO;use Ada.Text_IO;
procedure testall is
   package RIO is new Float_IO(Real);
   use RIO;
   use allx.RA;
   W : weight_array;
   D : RM := (others => (others => 1.0));
   procedure testallx(D1 : RM;
                      W1 : in out weight_array) is
   begin
      for i in 1..gK loop
         W1(i) := Real(i)*D1;
      end loop;
   end testallx;

begin
   Dx := 3;
   Dy := 5;
   gK := 3;
   testallx(D,W);
   for k in 1..Dx loop
      new_line(2);
      for i in 1..Dy loop
         new_line;
         for j in 1..gK loop
            RIO.put(W(k)(i,j));
         end loop;
      end loop;
   end loop;
end testall;

raised CONSTRAINT_ERROR : testall.adb:13  (W1(i) := ...)  index check failed, and of course if I use numbers in package allx, then W1(i) is known.
How to keep the dimensions Dx,Dy,gK open until execution?


^ permalink raw reply	[relevance 7%]

* Re: Erfc() function in ADA
  2019-04-02 10:39  4% ` gautier_niouzes
@ 2019-04-03 16:01  0%   ` leov
  0 siblings, 0 replies; 200+ results
From: leov @ 2019-04-03 16:01 UTC (permalink / raw)


On Tuesday, April 2, 2019 at 6:39:59 AM UTC-4, gautier...@hotmail.com wrote:
> A few random remarks...
> 
> 1) For further references: there is now in Mathpaqs (rev. 153+) a separate Erf_function package.
> Since Phi_function.Phi uses Erf(x) anyway, it's better to have access to Erf directly.
> 
> 2) About the Numerical Recipies: be careful, some versions support only 7-8 digits (single precision), so numerical errors cumulate very quickly.
> 
> 3) Some good stuff can be found in the Alglib and Cephes libraries, in C, Fortran or Pascal
> 
> 4) Simple special functions (with one parameter) could well be in an official Ada.Numerics.Generic_Special_Functions (low maintenance effort for compiler vendors)
> 
> 5) Don't forget to check: https://www.adaic.org/ada-resources/tools-libraries/
> 
> 6) Perhaps the Alire system has some math packages ?

Thanks for enhancing the library. I just ported my code and the Phi function is working like a charm.


^ permalink raw reply	[relevance 0%]

* Re: Erfc() function in ADA
  @ 2019-04-02 10:39  4% ` gautier_niouzes
  2019-04-03 16:01  0%   ` leov
  0 siblings, 1 reply; 200+ results
From: gautier_niouzes @ 2019-04-02 10:39 UTC (permalink / raw)


A few random remarks...

1) For further references: there is now in Mathpaqs (rev. 153+) a separate Erf_function package.
Since Phi_function.Phi uses Erf(x) anyway, it's better to have access to Erf directly.

2) About the Numerical Recipies: be careful, some versions support only 7-8 digits (single precision), so numerical errors cumulate very quickly.

3) Some good stuff can be found in the Alglib and Cephes libraries, in C, Fortran or Pascal

4) Simple special functions (with one parameter) could well be in an official Ada.Numerics.Generic_Special_Functions (low maintenance effort for compiler vendors)

5) Don't forget to check: https://www.adaic.org/ada-resources/tools-libraries/

6) Perhaps the Alire system has some math packages ?

^ permalink raw reply	[relevance 4%]

* Re: basic question on Ada programming
  2019-01-24  3:59  8% basic question on Ada programming Nasser M. Abbasi
@ 2019-01-24  7:58  6% ` Niklas Holsti
  0 siblings, 0 replies; 200+ results
From: Niklas Holsti @ 2019-01-24  7:58 UTC (permalink / raw)


On 19-01-24 05:59 , Nasser M. Abbasi wrote:
> I forgot these since I did not program in Ada for long time.
>
> Very basic question. In this
>
> ---------------------------
> with Ada.Text_Io;
> with Ada.Numerics.Real_Arrays;
>
> procedure main is
>   A : constant Ada.Numerics.Real_Arrays.Real_Matrix :=
>            (( 1.0,  2.0,  3.0),
>            ( 4.0,  5.0,  6.0),
>            ( 7.0,  8.0,  9.0));
>
>   v : constant Ada.Numerics.Real_Arrays.Real_Vector := (1.0,2.0,3.0);
>   procedure put (x : Ada.Numerics.Real_Arrays.Real_Vector) is
>     begin
>          FOR e of x LOOP
>              Ada.Text_Io.put_line(float'image(e));
>          END LOOP;
>    end put;
>    --use Ada.Numerics.Real_Arrays;
> begin
>     put(A*v); -- error here, since it does not see *
> end main;
> ------------------
>
> How can I write put(A*v) above, without having to do
>
>      use Ada.Numerics.Real_Arrays;
>
> above it?

Ada.Numerics.Real_Arrays."*" (A,v)

Or do "use type Ada.Numerics.Real_Arrays.Real_Matrix".

Or rename the operator "*" locally. But "use type" is better.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .


^ permalink raw reply	[relevance 6%]

* basic question on Ada programming
@ 2019-01-24  3:59  8% Nasser M. Abbasi
  2019-01-24  7:58  6% ` Niklas Holsti
  0 siblings, 1 reply; 200+ results
From: Nasser M. Abbasi @ 2019-01-24  3:59 UTC (permalink / raw)


I forgot these since I did not program in Ada for long time.

Very basic question. In this

---------------------------
with Ada.Text_Io;
with Ada.Numerics.Real_Arrays;

procedure main is
   A : constant Ada.Numerics.Real_Arrays.Real_Matrix :=
            (( 1.0,  2.0,  3.0),
            ( 4.0,  5.0,  6.0),
            ( 7.0,  8.0,  9.0));

   v : constant Ada.Numerics.Real_Arrays.Real_Vector := (1.0,2.0,3.0);
   procedure put (x : Ada.Numerics.Real_Arrays.Real_Vector) is
     begin
          FOR e of x LOOP
              Ada.Text_Io.put_line(float'image(e));
          END LOOP;
    end put;
    --use Ada.Numerics.Real_Arrays;
begin
     put(A*v); -- error here, since it does not see *
end main;
------------------

How can I write put(A*v) above, without having to do

      use Ada.Numerics.Real_Arrays;

above it?

I am trying to see if I can avoid doing use Ada.Numerics.Real_Arrays
so that I can explicitly add Ada.Numerics.Real_Arrays.something every
where, so I know where the something is coming from when looking at
the code.

But what about the *?  How to tell Ada it is coming from
Ada.Numerics.Real_Arrays without doing an explicit use? What
would the syntax be?

Using gnat community 2018.

Thanks
--Nasser


^ permalink raw reply	[relevance 8%]

* Re: overloading operators
  2018-11-26 18:03  0%           ` Simon Wright
@ 2018-11-26 18:24  0%             ` Dmitry A. Kazakov
  0 siblings, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2018-11-26 18:24 UTC (permalink / raw)


On 2018-11-26 19:03, Simon Wright wrote:
> Anh Vo <anhvofrcaus@gmail.com> writes:
> 
>> On Thursday, November 22, 2018 at 12:18:06 AM UTC-8, briot.e...@gmail.com wrote:
>>>> You can always say e.g. Ada.Numerics.Real_Arrays."*" (A, B) but it is
>>>> rather clumsy compared to A * B!
>>>
>>>
>>> The main use I have for that notation is in expression functions in specs,
>>> since we try to avoid use clauses in specs. So for instance:
>>>
>>>      function Greater (A, B : Some_Package.My_Type)  return Some_Package.My_Type
>>>          is (Some_Package.">" (A, B));
>>
>> What is wrong with "use type clause"?
> 
> Nothing, but OP was asking about what qualifications are available

Then I think one forgot qualification of the arguments:

   ...
   is (Some_Package.">" (Some_Package.Greater.A, Some_Package.Greater.B));

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de


^ permalink raw reply	[relevance 0%]

* Re: overloading operators
  2018-11-26 17:47  0%         ` Anh Vo
@ 2018-11-26 18:03  0%           ` Simon Wright
  2018-11-26 18:24  0%             ` Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: Simon Wright @ 2018-11-26 18:03 UTC (permalink / raw)


Anh Vo <anhvofrcaus@gmail.com> writes:

> On Thursday, November 22, 2018 at 12:18:06 AM UTC-8, briot.e...@gmail.com wrote:
>> > You can always say e.g. Ada.Numerics.Real_Arrays."*" (A, B) but it is
>> > rather clumsy compared to A * B!
>> 
>> 
>> The main use I have for that notation is in expression functions in specs,
>> since we try to avoid use clauses in specs. So for instance:
>> 
>>     function Greater (A, B : Some_Package.My_Type)  return Some_Package.My_Type
>>         is (Some_Package.">" (A, B));
>
> What is wrong with "use type clause"?

Nothing, but OP was asking about what qualifications are available

^ permalink raw reply	[relevance 0%]

* Re: overloading operators
  2018-11-22  8:18  0%       ` briot.emmanuel
  2018-11-22 11:39  0%         ` Simon Wright
@ 2018-11-26 17:47  0%         ` Anh Vo
  2018-11-26 18:03  0%           ` Simon Wright
  1 sibling, 1 reply; 200+ results
From: Anh Vo @ 2018-11-26 17:47 UTC (permalink / raw)


On Thursday, November 22, 2018 at 12:18:06 AM UTC-8, briot.e...@gmail.com wrote:
> > You can always say e.g. Ada.Numerics.Real_Arrays."*" (A, B) but it is
> > rather clumsy compared to A * B!
> 
> 
> The main use I have for that notation is in expression functions in specs,
> since we try to avoid use clauses in specs. So for instance:
> 
>     function Greater (A, B : Some_Package.My_Type)  return Some_Package.My_Type
>         is (Some_Package.">" (A, B));

What is wrong with "use type clause"?

Anh Vo


^ permalink raw reply	[relevance 0%]

* Re: overloading operators
  2018-11-22  8:18  0%       ` briot.emmanuel
@ 2018-11-22 11:39  0%         ` Simon Wright
  2018-11-26 17:47  0%         ` Anh Vo
  1 sibling, 0 replies; 200+ results
From: Simon Wright @ 2018-11-22 11:39 UTC (permalink / raw)


briot.emmanuel@gmail.com writes:

>> You can always say e.g. Ada.Numerics.Real_Arrays."*" (A, B) but it is
>> rather clumsy compared to A * B!
>
> The main use I have for that notation is in expression functions in specs,
> since we try to avoid use clauses in specs. So for instance:
>
>     function Greater (A, B : Some_Package.My_Type)  return Some_Package.My_Type
>         is (Some_Package.">" (A, B));

Good point (though return Boolean would be better :-)

Personally I try to avoid use clauses in body context clauses, too.

^ permalink raw reply	[relevance 0%]

* Re: overloading operators
  2018-11-21 17:37  5%     ` Simon Wright
@ 2018-11-22  8:18  0%       ` briot.emmanuel
  2018-11-22 11:39  0%         ` Simon Wright
  2018-11-26 17:47  0%         ` Anh Vo
  0 siblings, 2 replies; 200+ results
From: briot.emmanuel @ 2018-11-22  8:18 UTC (permalink / raw)


> You can always say e.g. Ada.Numerics.Real_Arrays."*" (A, B) but it is
> rather clumsy compared to A * B!


The main use I have for that notation is in expression functions in specs,
since we try to avoid use clauses in specs. So for instance:

    function Greater (A, B : Some_Package.My_Type)  return Some_Package.My_Type
        is (Some_Package.">" (A, B));


       

^ permalink raw reply	[relevance 0%]

* Re: overloading operators
  2018-11-21 16:39  5%   ` hnptz
@ 2018-11-21 17:37  5%     ` Simon Wright
  2018-11-22  8:18  0%       ` briot.emmanuel
  0 siblings, 1 reply; 200+ results
From: Simon Wright @ 2018-11-21 17:37 UTC (permalink / raw)


hnptz@yahoo.de writes:

> On Wednesday, November 21, 2018 at 2:50:05 PM UTC+1, AdaMagica wrote:
>> Am Mittwoch, 21. November 2018 10:56:09 UTC+1 schrieb hn...@yahoo.de:
>> > How can I use the old and the overloaded operator at the same time
>> > in the same program for the same type?
>> > For example: Overloaded "*" defined by user for type Real_Matrix
>> > and "*" defined in package Numerics.Real_Arrays for Real_Matrix.
>> 
>> For the nomenclature:
>> If I understand correctly what you're saying, it's not overloading,
>> but overriding what you're doing.
>> If you defined a function "*" for type Real_Matrix in a package of
>> your own, say Pack, the corresponding operation in the package where
>> Real_Matrix is defined, here Ada.Numerics, is hidden from direct and
>> use visibility in Pack. You can make it visible again via an
>> extended name.
>> So which "*" is visible at certain place depends on the kind of
>> visibility of Pack and Ada.Numerics. With proper name qualification,
>> both are callable at the same place in code.
>
> what would be a proper name qualification? Extended name for pack
> defined "*" in Ada.Numerics like pack."*"?

You can always say e.g. Ada.Numerics.Real_Arrays."*" (A, B) but it is
rather clumsy compared to A * B!


^ permalink raw reply	[relevance 5%]

* Re: overloading operators
  2018-11-21 13:50  6% ` AdaMagica
@ 2018-11-21 16:39  5%   ` hnptz
  2018-11-21 17:37  5%     ` Simon Wright
  0 siblings, 1 reply; 200+ results
From: hnptz @ 2018-11-21 16:39 UTC (permalink / raw)


On Wednesday, November 21, 2018 at 2:50:05 PM UTC+1, AdaMagica wrote:
> Am Mittwoch, 21. November 2018 10:56:09 UTC+1 schrieb hn...@yahoo.de:
> > How can I use the old and the overloaded operator at the same time in the same program for the same type?
> > For example: Overloaded  "*" defined by user for type Real_Matrix and "*" defined in package Numerics.Real_Arrays for Real_Matrix.
> 
> For the nomenclature:
> If I understand correctly what you're saying, it's not overloading, but overriding what you're doing.
> If you defined a function "*" for type Real_Matrix in a package of your own, say Pack, the corresponding operation in the package where Real_Matrix is defined, here Ada.Numerics, is hidden from direct and use visibility in Pack. You can make it visible again via an extended name.
> So which "*" is visible at certain place depends on the kind of visibility of Pack and Ada.Numerics. With proper name qualification, both are callable at the same place in code.


what would be a proper name qualification? Extended name for pack defined "*" in Ada.Numerics like pack."*"?

^ permalink raw reply	[relevance 5%]

* Re: overloading operators
  @ 2018-11-21 13:50  6% ` AdaMagica
  2018-11-21 16:39  5%   ` hnptz
  0 siblings, 1 reply; 200+ results
From: AdaMagica @ 2018-11-21 13:50 UTC (permalink / raw)


Am Mittwoch, 21. November 2018 10:56:09 UTC+1 schrieb hn...@yahoo.de:
> How can I use the old and the overloaded operator at the same time in the same program for the same type?
> For example: Overloaded  "*" defined by user for type Real_Matrix and "*" defined in package Numerics.Real_Arrays for Real_Matrix.

For the nomenclature:
If I understand correctly what you're saying, it's not overloading, but overriding what you're doing.
If you defined a function "*" for type Real_Matrix in a package of your own, say Pack, the corresponding operation in the package where Real_Matrix is defined, here Ada.Numerics, is hidden from direct and use visibility in Pack. You can make it visible again via an extended name.
So which "*" is visible at certain place depends on the kind of visibility of Pack and Ada.Numerics. With proper name qualification, both are callable at the same place in code.


^ permalink raw reply	[relevance 6%]

* Re: GNAT for AVR - Mathematical Functions
  2018-09-17  2:22  5% GNAT for AVR - Mathematical Functions ada.newcomer
  2018-09-17 12:22  0% ` Simon Wright
  2018-09-17 17:28  0% ` Bill Findlay
@ 2018-09-25  7:14  0% ` R R
  2 siblings, 0 replies; 200+ results
From: R R @ 2018-09-25  7:14 UTC (permalink / raw)


On Monday, September 17, 2018 at 4:22:47 AM UTC+2, Ada Newcomer wrote:
> Hello.
> 
> I'm programming an ATmega328P with the GNAT compiler for AVR.
> 
> I need to use the Sqrt, Arctan and Atan2 functions. But maybe in the future I will need to use some more.
> 
> I don't have access to the regular Ada.Numerics package.
> 
> By now, I wrote the Sqrt using the Newton's method and Arctan using Taylor series.
> 
> I would like to know if there is a better way to use/implement mathematical functions (maybe import them from C?).
> 
> I really appreciate any help.

The old AVR-ADA project never supported floting point math. The AVR 8bit processors are not made for that, even though you can use float and double in Arduino. The AVR compiler by Adacore from around 2011 did support floating point variables as far as I remember, I am not sure about the math functions.

regards
    Rolf

^ permalink raw reply	[relevance 0%]

* Re: GNAT for AVR - Mathematical Functions
  2018-09-17  2:22  5% GNAT for AVR - Mathematical Functions ada.newcomer
  2018-09-17 12:22  0% ` Simon Wright
@ 2018-09-17 17:28  0% ` Bill Findlay
  2018-09-25  7:14  0% ` R R
  2 siblings, 0 replies; 200+ results
From: Bill Findlay @ 2018-09-17 17:28 UTC (permalink / raw)


On 17 Sep 2018, ada.newcomer@gmail.com wrote
(in article<ed6bc2e2-a2e1-4a0b-b253-8142d47518c9@googlegroups.com>):

> Hello.
>
> I'm programming an ATmega328P with the GNAT compiler for AVR.
>
> I need to use the Sqrt, Arctan and Atan2 functions. But maybe in the future I
> will need to use some more.
>
> I don't have access to the regular Ada.Numerics package.
>
> By now, I wrote the Sqrt using the Newton's method and Arctan using Taylor
> series.
>
> I would like to know if there is a better way to use/implement mathematical
> functions (maybe import them from C?).
>
> I really appreciate any help.

Since you have sqrt, see:<http://www.findlayw.plus.com/KDF9/#ATN>

-- 
Bill Findlay


^ permalink raw reply	[relevance 0%]

* Re: GNAT for AVR - Mathematical Functions
  2018-09-17  2:22  5% GNAT for AVR - Mathematical Functions ada.newcomer
@ 2018-09-17 12:22  0% ` Simon Wright
  2018-09-17 17:28  0% ` Bill Findlay
  2018-09-25  7:14  0% ` R R
  2 siblings, 0 replies; 200+ results
From: Simon Wright @ 2018-09-17 12:22 UTC (permalink / raw)


ada.newcomer@gmail.com writes:

> I'm programming an ATmega328P with the GNAT compiler for AVR.
>
> I need to use the Sqrt, Arctan and Atan2 functions. But maybe in the
> future I will need to use some more.
>
> I don't have access to the regular Ada.Numerics package.
>
> By now, I wrote the Sqrt using the Newton's method and Arctan using
> Taylor series.
>
> I would like to know if there is a better way to use/implement
> mathematical functions (maybe import them from C?).
>
> I really appreciate any help.

For what it's worth, the FSF GCC arm-eabi compiler/runtime that I built
imports the basic maths functions from the C library. This may be
because I built the C library (newlib) first?

The GNAT CE arm-eabi compiler goes to basics with very deep-looking
code; possibly because it's "the Ada Cert Math specific version" (from
s-libsin.ads), i.e. one with which AdaCore will support customers with
certification requirements.


^ permalink raw reply	[relevance 0%]

* GNAT for AVR - Mathematical Functions
@ 2018-09-17  2:22  5% ada.newcomer
  2018-09-17 12:22  0% ` Simon Wright
                   ` (2 more replies)
  0 siblings, 3 replies; 200+ results
From: ada.newcomer @ 2018-09-17  2:22 UTC (permalink / raw)


Hello.

I'm programming an ATmega328P with the GNAT compiler for AVR.

I need to use the Sqrt, Arctan and Atan2 functions. But maybe in the future I will need to use some more.

I don't have access to the regular Ada.Numerics package.

By now, I wrote the Sqrt using the Newton's method and Arctan using Taylor series.

I would like to know if there is a better way to use/implement mathematical functions (maybe import them from C?).

I really appreciate any help.

^ permalink raw reply	[relevance 5%]

* Re: Simple hash or pseudo-random function
  2018-07-16 17:17  4% ` Jeffrey R. Carter
@ 2018-07-16 21:14  0%   ` gautier_niouzes
  0 siblings, 0 replies; 200+ results
From: gautier_niouzes @ 2018-07-16 21:14 UTC (permalink / raw)


Le lundi 16 juillet 2018 19:17:49 UTC+2, Jeffrey R. Carter a écrit :

> Not sure what you mean by "an integer in a range of minimum length 365". You 
> could simply use a RNG to generate 64-bit values and xor them with your values 
> if you want a 64-bit result. By setting the initial seed, the sequence would be 
> repeatable. Ada.Numerics.Discrete_Random would probably serve. If it's too slow, 
> the PragmAda Reusable Components includes KISS, a very fast, pretty good RNG. It 
> produces 32-bit values, so you'd probably need to call it twice.

The 64-bit value is the *input* and the output is a function of that input only.
e.g.
10562032 gives always 211
31375393 gives always 31
85232830 gives always 172
NB: the input codes can appear in a different order, so a pseudo-random *sequence* cannot be used.

I've tested different RNG's by initializing them with the input code and using only the first pseudo-random value using that seed. The good news is that they seem uniformly distributed even with successive seed values, but they are not random enough when seeds are similar. I'll check Marius' solution, or a hash function like CRC.


^ permalink raw reply	[relevance 0%]

* Re: Simple hash or pseudo-random function
  @ 2018-07-16 17:17  4% ` Jeffrey R. Carter
  2018-07-16 21:14  0%   ` gautier_niouzes
  0 siblings, 1 reply; 200+ results
From: Jeffrey R. Carter @ 2018-07-16 17:17 UTC (permalink / raw)


On 07/16/2018 10:20 AM, gautier_niouzes@hotmail.com wrote:
> 
> Does someone have a function that would take an integer (range 0 .. 2**63), not uniformily distributed (it's a code with some meaning) and return a number that is pseudo-random, uniformily distributed (could be a floating-point number or an integer in a range of minimum length 365) ?
> The difficulty for me is to find a very simple function. There are many that are for hashing strings, but they could be too time-consuming: it's for a number-crunching program where this function will be called billions of times, so I'm looking for something really simple (and fast :-) ).

Not sure what you mean by "an integer in a range of minimum length 365". You 
could simply use a RNG to generate 64-bit values and xor them with your values 
if you want a 64-bit result. By setting the initial seed, the sequence would be 
repeatable. Ada.Numerics.Discrete_Random would probably serve. If it's too slow, 
the PragmAda Reusable Components includes KISS, a very fast, pretty good RNG. It 
produces 32-bit values, so you'd probably need to call it twice.

-- 
Jeff Carter
"If you don't get the President of the United States on that
phone, ... you're going to have to answer to the Coca-Cola
Company."
Dr. Strangelove
32

^ permalink raw reply	[relevance 4%]

* Re: Memory pools
  @ 2018-05-31 19:33  3% ` gorgelo
  0 siblings, 0 replies; 200+ results
From: gorgelo @ 2018-05-31 19:33 UTC (permalink / raw)


And to follow up on the naive benchmarks:
https://github.com/frol/completely-unscientific-benchmarks

Using the memory pool in the previous post it can be used to implement the Treap algorithm (after some minor modifications):

pragma Suppress (Tampering_Check);
-- Tampering checks are only for multi-task applications.
-- Since this application is single task we can safely
-- suppress tampering checks of the standard containers.
-- If performance is an issue, the Ada-Traits Containers may be used instead.

with System.Storage_Elements;
with System.Storage_Pools;
with Ada.Text_IO;
with Ada.Integer_Text_IO;
with Ada.Containers.Vectors;
with Ada.Unchecked_Deallocation;
with Ada.Numerics.Discrete_Random;

procedure Main is

   subtype Storage_Offset is System.Storage_Elements.Storage_Offset;
   subtype Storage_Count  is System.Storage_Elements.Storage_Count;
   subtype Storage_Array  is System.Storage_Elements.Storage_Array;

   subtype Root_Storage_Pool is System.Storage_Pools.Root_Storage_Pool;

   subtype Integer_Address is System.Storage_Elements.Integer_Address;

   subtype Count_Type is Ada.Containers.Count_Type;

   use type Count_Type;
   use type Storage_Offset;
   use type Integer_Address;

   procedure Put (Text : String) renames Ada.Text_IO.Put;

   procedure Put_Line (Text : String) renames Ada.Text_IO.Put_Line;

   procedure Put_Line (I : Integer) is
   begin
      Ada.Integer_Text_IO.Put (I, 0);
      Ada.Text_IO.New_Line;
   end Put_Line;

   procedure Put (I : Integer) is
   begin
      Ada.Integer_Text_IO.Put (I, 0);
   end Put;

   procedure Put (I : Storage_Offset) is
   begin
      Ada.Integer_Text_IO.Put (Integer (I), 0);
   end Put;

   function To_Integer (Value : System.Address) return Integer_Address
                        renames System.Storage_Elements.To_Integer;

   generic
      Slot_Size : Positive;
      -- Specifies the size of each slot in Storage Elements (bytes)
      -- Must be big enough to store any object one wishes to allocate
      -- inside the memory pool.

      MAX : Positive;
      -- Specifies the number of slots that will be allocated in an array
      -- from the heap every time more memory needs to be pre-allocated.

   package Arena_Pools is

      type Arena (<>) is new Root_Storage_Pool with private;

      function Make return Arena;

      overriding
      procedure Allocate
        (  Pool      : in out Arena;
           Address   : out System.Address;
           Size      : Storage_Count;
           Alignment : Storage_Count
          );

      overriding
      procedure Deallocate
        (  Pool      : in out Arena;
           Address   : System.Address;
           Size      : Storage_Count;
           Alignment : Storage_Count
          );

      overriding
      function Storage_Size (Pool : Arena) return Storage_Count;
      -- Approximation of how many Storage Elements (bytes)
      -- have been heap-allocated.

   private

      type Slot is record
         Elements : Storage_Array (1..Storage_Offset (Slot_Size));
      end record;

      subtype Slot_Index is Storage_Offset range 1.. Storage_Offset (MAX);

      type Slots_Array is array (Slot_Index) of Slot;

      subtype Free_Index is Integer range 1..MAX;
      -- This Integer type (32-bits) is created in order to not use the type
      -- Storage_Offset (64-bits) in the free indices vector.

      package Indices_Vector is new Ada.Containers.Vectors
        (Index_Type   => Positive,
         Element_Type => Free_Index,
         "="          => "=");

      type Slots_Envelope is record
         Items        : Slots_Array;
         Free_Indices : Indices_Vector.Vector;
      end record;

      type Slots_Envelope_Ptr is access all Slots_Envelope;

      package Envelope_Vectors is new Ada.Containers.Vectors
        (Index_Type   => Positive,
         Element_Type => Slots_Envelope_Ptr,
         "="          => "=");

      type Arena is new Root_Storage_Pool with record
         Index : Positive := 1;
         -- Indicates which array of slots to first search for a free index

         Envelopes : Envelope_Vectors.Vector;
      end record;

      overriding
      procedure Finalize (This : in out Arena);
      -- Deallocates all allocated memory from the heap

   end Arena_Pools;

   package body Arena_Pools is

      function Make return Slots_Envelope_Ptr is
         Envelope : Slots_Envelope_Ptr := new Slots_Envelope;
      begin
         Envelope.Free_Indices.Reserve_Capacity (Ada.Containers.Count_Type (MAX));
         for I in Slot_Index'Range loop
            Envelope.Free_Indices.Append (Free_Index (I));
         end loop;

         return Envelope;
      end Make;

      function Make return Arena is
         Envelope : Slots_Envelope_Ptr := Make;
      begin
         return This : Arena do
            This.Envelopes.Append (Envelope);
         end return;
      end Make;

      function Determine_Index (Pool    : Arena;
                                Address : System.Address) return Positive is
         Searched_For : Natural := 0;
         First_Address : System.Address;
         Last_Address  : System.Address;
      begin
         for I in Pool.Envelopes.First_Index..Pool.Envelopes.Last_Index loop
            First_Address := Pool.Envelopes (I).Items (1)'Address;
            Last_Address  := Pool.Envelopes (I).Items (Storage_Offset (MAX))'Address;
            if
              To_Integer (First_Address) <= To_Integer (Address) and
              To_Integer (Address)       <= To_Integer (Last_Address)
            then
               Searched_For := I;
               exit;
            end if;
         end loop;

         if Searched_For = 0 then
            raise Storage_Error;
         end if;

         return Searched_For;
      end Determine_Index;

      procedure Allocate
        (Pool      : in out Arena;
         Address   : out System.Address;
         Size      : Storage_Count;
         Alignment : Storage_Count)
      is
         Id : Slot_Index;
      begin
         if Pool.Envelopes (Pool.Index).Free_Indices.Length > 0 then
            Id := Slot_Index (Pool.Envelopes (Pool.Index).Free_Indices.Last_Element);
            Pool.Envelopes (Pool.Index).Free_Indices.Delete_Last;
         else
            declare
               Has_Found : Boolean := False;
            begin
               for I in Pool.Envelopes.First_Index .. Pool.Envelopes.Last_Index loop
                  if Pool.Envelopes (I).Free_Indices.Length > 0 then
                     Pool.Index := I;
                     Id := Slot_Index (Pool.Envelopes (Pool.Index).Free_Indices.Last_Element);
                     Pool.Envelopes (Pool.Index).Free_Indices.Delete_Last;
                     Has_Found := True;
                     exit;
                  end if;
               end loop;

               if not Has_Found then
                  declare
                     E : Slots_Envelope_Ptr := Make;
                  begin
                     Pool.Envelopes.Append (E);
                     Pool.Index := Pool.Envelopes.Last_Index;
                     Id := Slot_Index (Pool.Envelopes (Pool.Index).Free_Indices.Last_Element);
                     Pool.Envelopes (Pool.Index).Free_Indices.Delete_Last;
                  end;
               end if;
            end;
         end if;

         Address := Pool.Envelopes (Pool.Index).Items (Id).Elements'Address;
      end Allocate;

      procedure Deallocate (Pool      : in out Arena;
                            Address   : System.Address;
                            Size      : Storage_Count;
                            Alignment : Storage_Count)
      is
         I : constant Positive := Determine_Index (Pool, Address);

         First_Address : System.Address;
         Last_Address  : System.Address;

         Slot_Id : Slot_Index;

         D : Integer_Address;
      begin
         First_Address := Pool.Envelopes (I).Items (1)'Address;
         Last_Address  := Pool.Envelopes (I).Items (Storage_Offset (MAX))'Address;

         D := (To_Integer (Last_Address) - To_Integer (First_Address) + Integer_Address (Slot_Size)) / Integer_Address (MAX);

         Slot_Id := Slot_Index ((To_Integer (Address) + Integer_Address (Slot_Size) - To_Integer (First_Address))/ D);

         Pool.Envelopes (I).Free_Indices.Append (Free_Index (Slot_Id));
      end Deallocate;

      function Storage_Size (Pool : Arena) return Storage_Count is
         Result : Storage_Count := 0;
      begin
         for Envelope of Pool.Envelopes loop
            Result := Storage_Count (Slot_Size*MAX) + Storage_Count (Envelope.Free_Indices.Capacity * 4);
         end loop;

         return Result;
      end Storage_Size;

      procedure Free is new Ada.Unchecked_Deallocation (Object => Slots_Envelope,
                                                        Name   => Slots_Envelope_Ptr);

      procedure Finalize (This : in out Arena) is
      begin
         for Envelope of This.Envelopes loop
            Free (Envelope);
         end loop;
         This.Envelopes.Clear;
      end Finalize;

   end Arena_Pools;

   package Pools is new Arena_Pools (24, 200_000);

   Pool : Pools.Arena := Pools.Make;

   -- Here ends the definition of the Storage pool and here begins
   -- implementation of the algorithm.

   package Integer_Random is new Ada.Numerics.Discrete_Random (Integer);

   G : Integer_Random.Generator;

   type Node;
   type Node_Ptr is access all Node with
     Storage_Pool => Pool;

   type Node is record
      Left  : Node_Ptr;
      Right : Node_Ptr;
      X     : Integer := 0;
      Y     : Integer := Integer_Random.Random (G);
   end record with
     Size => 24*8;

   package Tree_Def is

      type Tree is tagged private;

      function Has_Value (T : in out Tree;
                          X : in     Integer) return Boolean;

      procedure Insert (T : in out Tree;
                        X : in     Integer);

      procedure Erase (T : in out Tree;
                       X : in     Integer);

   private

      function Merge (Lower   : Node_Ptr;
                      Greater : Node_Ptr) return Node_Ptr;

      function Merge (Lower   : Node_Ptr;
                      Equal   : Node_Ptr;
                      Greater : Node_Ptr) return Node_Ptr;

      procedure Split (Orig             : in     Node_Ptr;
                       Lower            : in out Node_Ptr;
                       Greater_Or_Equal : in out Node_Ptr;
                       Value            : in     Integer);

      procedure Split (Orig    : in     Node_Ptr;
                       Lower   : in out Node_Ptr;
                       Equal   : in out Node_Ptr;
                       Greater : in out Node_Ptr;
                       Value   : in     Integer);

      procedure Make_Node (Node :    out Node_Ptr;
                           X    : in     Integer);

      type Tree is tagged record
         Root: Node_Ptr := null;
      end record;

   end Tree_Def;

   package body Tree_Def is

      procedure Free is new Ada.Unchecked_Deallocation(Object => Node,
                                                       Name   => Node_Ptr);

      procedure Make_Node (Node :    out Node_Ptr;
                           X    : in     Integer) is
      begin
         Node := new Main.Node;
         Node.X := X;
         Node.Y := Integer_Random.Random (G);
      end Make_Node;

      procedure Delete_Node (Node : in out Node_Ptr) is
      begin
         if Node /= null then
            if Node.Left /= null then
               Delete_Node(Node.Left);
            end if;

            if Node.Right /= null then
               Delete_Node (Node.Right);
            end if;

            Free (Node);
         end if;
      end Delete_Node;

      function Merge (Lower   : Node_Ptr;
                      Greater : Node_Ptr) return Node_Ptr is
      begin
         if Lower = null then
            return Greater;
         end if;

         if Greater = null then
            return lower;
         end if;

         if Lower.Y < Greater.Y then
            Lower.Right := Merge (Lower.Right, Greater);
            return Lower;
         else
            Greater.Left := Merge (Lower, Greater.Left);
            return Greater;
         end if;
      end Merge;

      function Merge (Lower   : Node_Ptr;
                      Equal   : Node_Ptr;
                      Greater : Node_Ptr) return Node_Ptr is
      begin
         return Merge (Merge (Lower, Equal), Greater);
      end merge;

      procedure Split (Orig             : in     Node_Ptr;
                       Lower            : in out Node_Ptr;
                       Greater_Or_Equal : in out Node_Ptr;
                       Value            : in     Integer) is
      begin
         if Orig = null then
            Lower := null;
            Greater_Or_Equal := null;
            return;
         end if;
         if Orig.X < Value then
            Lower := Orig;
            Split (Lower.Right, Lower.Right, Greater_Or_Equal, Value);
         else
            Greater_Or_Equal := Orig;
            Split (Greater_Or_Equal.Left, Lower, Greater_Or_Equal.Left, Value);
         end if;
      end Split;

      procedure Split (Orig    : in     Node_Ptr;
                       Lower   : in out Node_Ptr;
                       Equal   : in out Node_Ptr;
                       Greater : in out Node_Ptr;
                       Value   : in     Integer)
      is
         Equal_Or_Greater: Node_Ptr;
      begin
         Split (Orig, Lower, Equal_Or_Greater, Value);
         Split (Equal_Or_Greater, Equal, Greater, Value + 1);
      end Split;

      function Has_Value (T : in out Tree;
                          X : in     Integer) return Boolean
      is
         Lower   : Node_Ptr;
         Equal   : Node_Ptr;
         Greater : Node_Ptr;

         Result : Boolean;
      begin
         Split (T.Root, Lower, Equal, Greater, X);
         Result := Equal /= null;
         T.Root := Merge (Lower, Equal, Greater);
         return Result;
      end Has_Value;

      procedure Insert (T : in out Tree;
                        X : in     Integer)
      is
         Lower   : Node_Ptr;
         Equal   : Node_Ptr;
         Greater : Node_Ptr;
      begin
         Split (T.Root, Lower, Equal, Greater, X);
         if Equal = null then
            Make_Node (Equal, X);
         end if;
         T.Root := Merge (Lower, Equal, Greater);
      end Insert;

      procedure Erase (T : in out Tree;
                       X : in     Integer) is
         Lower   : Node_Ptr;
         Equal   : Node_Ptr;
         Greater : Node_Ptr;
      begin
         Split (T.Root, Lower, Equal, Greater, X);
         T.Root := Merge (Lower, Greater);
         -- commenting out the following line
         -- doesn't seem to affect running time by much, if at all
         Delete_Node (Equal);
      end Erase;

   end Tree_Def;

   Tree    : Tree_Def.Tree;
   Current : Integer := 5;
   Result  : Integer := 0;
   Mode    : Integer;

begin
   Integer_Random.Reset (G);

   for I in 1..1_000_000 loop
      Mode := I mod 3;
      Current := (Current * 57 + 43) mod 10007;
      if Mode = 0 then
         Tree.Insert (Current);
      elsif Mode = 1 then
         Tree.Erase (Current);
      else
         Result := Result + (if Tree.Has_Value (Current) then 1 else 0);
      end if;
   end loop;
   Put_Line (Result);

end Main;

^ permalink raw reply	[relevance 3%]

* Re: why "unconstrained subtype in component declaration" while said component given default value ?
  2018-05-26 23:55  0%     ` Jere
@ 2018-05-27  0:14  0%       ` Jere
  0 siblings, 0 replies; 200+ results
From: Jere @ 2018-05-27  0:14 UTC (permalink / raw)


On Saturday, May 26, 2018 at 7:55:36 PM UTC-4, Jere wrote:
> On Saturday, May 26, 2018 at 6:11:13 PM UTC-4, Mehdi Saada wrote:
> > But isn't the situation the same in automatic variables, with arrays whose constraint is only known at run time ? Like this:
> > procedure Main is
> >    subtype Pos_Little is Positive range 1..56;
> >    package Num_Gen is new Ada.Numerics.Discrete_Random (Pos_Little);
> >    Gen : Num_Gen.Generator;
> > begin
> >    declare
> >       Arr : array (1..Num_Gen.Random(Gen)) of Positive;
> >    begin
> >       null;
> >    end;
> > end Main;
> > Yet this case is legal.
> 
> Record types need to support Representation Clauses, where as normal 
> variables do not.

Actually, since you can do the one Shark8 showed at runtime as well, I 
am not sure of the "why" anymore.  I'll have to think on it or perhaps
someone else will chime in.

^ permalink raw reply	[relevance 0%]

* Re: why "unconstrained subtype in component declaration" while said component given default value ?
  2018-05-26 22:11  5%   ` Mehdi Saada
@ 2018-05-26 23:55  0%     ` Jere
  2018-05-27  0:14  0%       ` Jere
  0 siblings, 1 reply; 200+ results
From: Jere @ 2018-05-26 23:55 UTC (permalink / raw)


On Saturday, May 26, 2018 at 6:11:13 PM UTC-4, Mehdi Saada wrote:
> But isn't the situation the same in automatic variables, with arrays whose constraint is only known at run time ? Like this:
> procedure Main is
>    subtype Pos_Little is Positive range 1..56;
>    package Num_Gen is new Ada.Numerics.Discrete_Random (Pos_Little);
>    Gen : Num_Gen.Generator;
> begin
>    declare
>       Arr : array (1..Num_Gen.Random(Gen)) of Positive;
>    begin
>       null;
>    end;
> end Main;
> Yet this case is legal.

Record types need to support Representation Clauses, where as normal 
variables do not.

^ permalink raw reply	[relevance 0%]

* Re: why "unconstrained subtype in component declaration" while said component given default value ?
  @ 2018-05-26 22:11  5%   ` Mehdi Saada
  2018-05-26 23:55  0%     ` Jere
  0 siblings, 1 reply; 200+ results
From: Mehdi Saada @ 2018-05-26 22:11 UTC (permalink / raw)


But isn't the situation the same in automatic variables, with arrays whose constraint is only known at run time ? Like this:
procedure Main is
   subtype Pos_Little is Positive range 1..56;
   package Num_Gen is new Ada.Numerics.Discrete_Random (Pos_Little);
   Gen : Num_Gen.Generator;
begin
   declare
      Arr : array (1..Num_Gen.Random(Gen)) of Positive;
   begin
      null;
   end;
end Main;
Yet this case is legal.


^ permalink raw reply	[relevance 5%]

* Re: How to get Ada to “cross the chasm”?
  @ 2018-05-06 16:58  6%                     ` Jacob Sparre Andersen
  0 siblings, 0 replies; 200+ results
From: Jacob Sparre Andersen @ 2018-05-06 16:58 UTC (permalink / raw)


Paul Rubin wrote:
> Niklas Holsti <niklas.holsti@tidorum.invalid> writes:

>> One reason is that when a function evaluates an expression that
>> creates an object of a large, dynamic size (eg. an array expression)
>> on the secondary stack, this object can be returned /in situ/ as the
>> function's return value, without being copied.
>
> Ok, but that pattern is so common that allocating the space in the
> primary stack before calling the function is a standard optimization
> that every serious C++ compiler knows how to do.  Then the function
> writes the result into the primary stack and the caller can still use
> it after the function returns.  Could Ada not do it the same way?

How would you do it with this example?

   with Ada.Numerics.Discrete_Random;
   with Ada.Strings.Fixed;
   with Ada.Text_IO;
   
   procedure Random_String is
   
      subtype Lengths is Integer range 10 .. 20;
   
      package Random_Lengths is
        new Ada.Numerics.Discrete_Random (Result_Subtype => Lengths);
   
      Generator : Random_Lengths.Generator;
   
      function Example (C : in Character) return String is
         use Ada.Strings.Fixed;
      begin
         return Random_Lengths.Random (Generator) * C;
      end Example;
   
   begin
      Random_Lengths.Reset (Generator);
   
      Ada.Text_IO.Put_Line (Example ('H'));
      Ada.Text_IO.Put_Line (Example ('e'));
      Ada.Text_IO.Put_Line (Example ('l'));
      Ada.Text_IO.Put_Line (Example ('l'));
      Ada.Text_IO.Put_Line (Example ('o'));
   end Random_String;

Greetings,

Jacob
-- 
»But you have to be a bit wary of a ship that collects
 snowflakes.«                                  -- Diziet Sma

^ permalink raw reply	[relevance 6%]

* Re: Generic library design
  2018-04-06 13:22  7% Generic library design Marius Amado-Alves
@ 2018-04-07  2:32  0% ` Randy Brukardt
  0 siblings, 0 replies; 200+ results
From: Randy Brukardt @ 2018-04-07  2:32 UTC (permalink / raw)



"Marius Amado-Alves" <amado.alves@gmail.com> wrote in message 
news:1d9faa0f-d3d7-4eb4-aa88-b50ed1e9aac3@googlegroups.com...
...
> Consider the running example: why is Ada.Numerics.Generic_Complex_Arrays
> parametrized by packages, instead of just a Real type and then instantiate 
> the
> packages intarnally?

When you do that, you are insisting on a new complex type with each 
instantiation of the complex arrays package. But perhaps you want one 
complex type and several complex array instantiations. (That makes more 
sense when the index subtype is a parameter to the generic; one certainly 
might want arrays indexed by different types.)

> And are compilers smart enough to merge identical instances w.r.t.
>to their generic arguments? Maybe with help of qualification pragmas
>telling there is no state?

Depends on the compiler. Janus/Ada shares all generic bodies (with all of 
the overhead that entails), so it is an extreme version. Other compilers 
don't try to share anything. Some are somewhere in the middle.

Note that argubly sharing based on generic parameters is (was?) patented and 
not usable by implementers without legal issues.

> No need to answer to all questions at once:-)

OK, the above is enough. :-)

              Randy.


^ permalink raw reply	[relevance 0%]

* Generic library design
@ 2018-04-06 13:22  7% Marius Amado-Alves
  2018-04-07  2:32  0% ` Randy Brukardt
  0 siblings, 1 reply; 200+ results
From: Marius Amado-Alves @ 2018-04-06 13:22 UTC (permalink / raw)


Hello hive mind. Designing a few generic libraries involving real and complex number types and arrays thereof. Undecided as to the type of generic parameter(s). Namely:

When should the parameter(s) be the base real type like (examples drawn from the standard, please extrapolate)

   generic
      type Real is digits <>;
   package Ada.Numerics.Generic_Real_Arrays is
   ...

with the necessary sidekicks e.g. Generic_Elementary_Functions instantiated internally,

when should it be one or more packages like 

   generic
      with package Real_Arrays   is new
         Ada.Numerics.Generic_Real_Arrays   (<>);
      use Real_Arrays;
      with package Complex_Types is new
         Ada.Numerics.Generic_Complex_Types (Real);
      use Complex_Types;
   package Ada.Numerics.Generic_Complex_Arrays is
   ...

with the set or a subset of the necessary entities "pre-instantiated" by the user? Is there a design "rule"?

Consider the running example: why is Ada.Numerics.Generic_Complex_Arrays parametrized by packages, instead of just a Real type and then instantiate the packages intarnally?

And are compilers smart enough to merge identical instances w.r.t. to their generic arguments? Maybe with help of qualification pragmas telling there is no state?

No need to answer to all questions at once:-)

Thanks a lot.


^ permalink raw reply	[relevance 7%]

* Re: Mathpaqs release 13-Mar-2018
  @ 2018-03-16 17:59  4%   ` gautier_niouzes
  0 siblings, 0 replies; 200+ results
From: gautier_niouzes @ 2018-03-16 17:59 UTC (permalink / raw)


Hi Vincent,

> Just a few questions :
> - why not use the standard Generic Real Arrays ?
Good point! I'll update the web site with a remark from g_matrices.ads: "NB: For Ada 2005+ and real numbers implemented as floating-point numbers, it is better to use Ada.Numerics.Generic_Real_Arrays instead.". An usage of G_Matrices can be for complex, rational, "bignum"-rationals, etc. ...

> - Are the G_Matrices stored in Fortran convention, i.e. Column Major Order ?
By default not, but you can add a pragma Convention.

> - Are they compatible with Blas & Lapack ?
Some stuff in the lin_alg area is, but frankly it is a bit rusty (in my head)...

> - Are the SparseB matrices compatible with Matlab matrices (i.e. CSC matrices)
SparseB is just a helper for Sparse package (I did it in Ada 83 around end 1990's, it would be a private child package now (tbd)...).
There are two bodies for sparseb: one standalone, one using Blas (sparseb.blas.adb)

> - Are both format interoperable ?
> - Are they interchangeable, i.e is there a common class type to manipulate them?

I've used for research purposes, interchangeably:
- plain matrices,
- band matrices (a matrix with zeroes outside diagonals and the cells just above and below) and
- sparse matrices.
I did it through generics.

^ permalink raw reply	[relevance 4%]

* Re: 64-bit unsigned integer?
  @ 2018-03-01  8:35  5%               ` Simon Wright
  0 siblings, 0 replies; 200+ results
From: Simon Wright @ 2018-03-01  8:35 UTC (permalink / raw)


Niklas Holsti <niklas.holsti@tidorum.invalid> writes:

> As long as the new numeric libraries let us write computations using
> the normal algebraic syntax (A * B + C), I have nothing against
> library solutions.

See Ada.Numerics.Generic_Real_Arrays.

Also, operator precedence is defined by the operator, not the package in
which it's declared for a particular type.


^ permalink raw reply	[relevance 5%]

* Re: GNAT can't vectorize Real_Matrix multiplication from Ada.Numerics.Real_Arrays. What a surprise!
  2018-02-20  2:31  5%               ` Bojan Bozovic
@ 2018-02-26  6:58  5%                 ` Robert Eachus
  0 siblings, 0 replies; 200+ results
From: Robert Eachus @ 2018-02-26  6:58 UTC (permalink / raw)


On Monday, February 19, 2018 at 9:31:26 PM UTC-5, Bojan Bozovic 

> I have looked at ATLAS, however it can't spawn more threads than specified at compile time, so there's lots of possibility to optimize there, by spawning as many threads as supported at run-time.

Aarrg!  Yes, there is a lot of work that needs to be done.  The intent is that you run ATLAS on your target environment, then use the best result as your blas library.

But the problem I am fighting with right now is that on the most recent (high-end) processors from Intel and AMD, you never want to use as many threads as the hardware tells you are available at run-time.  In fact, it is common that if you have a processor which supports 8-threads, you want to run four threads on all even or odd numbered threads.  The recent Threadripper and EPYC CPUs from AMD make it even more complex, as do any multisocket systems.  Usually you want to split the problem up completely and duplicate the data on each hardware CPU chip.


^ permalink raw reply	[relevance 5%]

* Re: GNAT can't vectorize Real_Matrix multiplication from Ada.Numerics.Real_Arrays. What a surprise!
  2018-02-19 21:08  5%             ` Robert Eachus
@ 2018-02-20  2:31  5%               ` Bojan Bozovic
  2018-02-26  6:58  5%                 ` Robert Eachus
  0 siblings, 1 reply; 200+ results
From: Bojan Bozovic @ 2018-02-20  2:31 UTC (permalink / raw)


On Monday, February 19, 2018 at 10:08:41 PM UTC+1, Robert Eachus wrote:
> On Sunday, February 18, 2018 at 4:48:42 PM UTC-5, Nasser M. Abbasi wrote:
> > On 2/18/2018 1:38 PM, Bojan Bozovic wrote:
> > 
> > If you are doing A*B by hand, then you are doing something
> > wrong. Almost all languages end up calling Blas
> > Fortran libraries for these operations. Your code and
> > the Ada code can't be faster.
> > 
> > http://www.netlib.org/blas/
> > 
> > Intel Math Kernel Library has all these.
> > 
> > https://en.wikipedia.org/wiki/Math_Kernel_Library
> 
> For multiplying two small matrices, blas is overkill and will be slower.  If you have say, 1000x1000 matrices, then you should be using blas.  But which BLAS?  Intel and AMD both have math libraries optimized for their CPUs.  However, I tend to use ATLAS.  ATLAS will build a blas targeted at your specific hardware.  This is not just about instruction set additions like SIMD2.  It will tailor the implementation to your number of cores and supported threads, cache sizes, and memory speeds.  I've also used the goto blas, but ATLAS even though not perfect, builds all of blas3 using matrix multiplication and blas2, such that all operations slower than O(n^2) have their speed determined by matrix multiplication.  (Then use multiple matrix multiplication codes with different parameters to find the fastest.)
> 
> Usually hardware vendor libraries catch up to and surpass ATLAS, but by then the hardware is obsolete. :-(   The other problem right now is that blas libraries are pretty dumb when it comes to multiprocessor systems.  I'm working on fixing that. ;-)

I have looked at ATLAS, however it can't spawn more threads than specified at compile time, so there's lots of possibility to optimize there, by spawning as many threads as supported at run-time. Ada would do much better here than C, because you could make portable code without resorting to ugly hacks of C, and using parallelism no matter whats the underlying processor architecture. That are my $0.02, worthless or not (and if you want to use assembler to "optimize" further in C, that can be done in any language, which I fear Intel MKL library and other vendor libraries do).


^ permalink raw reply	[relevance 5%]

* Re: GNAT can't vectorize Real_Matrix multiplication from Ada.Numerics.Real_Arrays. What a surprise!
  2018-02-18 21:48  6%           ` Nasser M. Abbasi
  2018-02-18 22:50 11%             ` Bojan Bozovic
@ 2018-02-19 21:08  5%             ` Robert Eachus
  2018-02-20  2:31  5%               ` Bojan Bozovic
  1 sibling, 1 reply; 200+ results
From: Robert Eachus @ 2018-02-19 21:08 UTC (permalink / raw)


On Sunday, February 18, 2018 at 4:48:42 PM UTC-5, Nasser M. Abbasi wrote:
> On 2/18/2018 1:38 PM, Bojan Bozovic wrote:
> 
> If you are doing A*B by hand, then you are doing something
> wrong. Almost all languages end up calling Blas
> Fortran libraries for these operations. Your code and
> the Ada code can't be faster.
> 
> http://www.netlib.org/blas/
> 
> Intel Math Kernel Library has all these.
> 
> https://en.wikipedia.org/wiki/Math_Kernel_Library

For multiplying two small matrices, blas is overkill and will be slower.  If you have say, 1000x1000 matrices, then you should be using blas.  But which BLAS?  Intel and AMD both have math libraries optimized for their CPUs.  However, I tend to use ATLAS.  ATLAS will build a blas targeted at your specific hardware.  This is not just about instruction set additions like SIMD2.  It will tailor the implementation to your number of cores and supported threads, cache sizes, and memory speeds.  I've also used the goto blas, but ATLAS even though not perfect, builds all of blas3 using matrix multiplication and blas2, such that all operations slower than O(n^2) have their speed determined by matrix multiplication.  (Then use multiple matrix multiplication codes with different parameters to find the fastest.)

Usually hardware vendor libraries catch up to and surpass ATLAS, but by then the hardware is obsolete. :-(   The other problem right now is that blas libraries are pretty dumb when it comes to multiprocessor systems.  I'm working on fixing that. ;-)

^ permalink raw reply	[relevance 5%]

* Re: GNAT can't vectorize Real_Matrix multiplication from Ada.Numerics.Real_Arrays. What a surprise!
  2018-02-18 21:48  6%           ` Nasser M. Abbasi
@ 2018-02-18 22:50 11%             ` Bojan Bozovic
  2018-02-19 21:08  5%             ` Robert Eachus
  1 sibling, 0 replies; 200+ results
From: Bojan Bozovic @ 2018-02-18 22:50 UTC (permalink / raw)


On Sunday, February 18, 2018 at 10:48:42 PM UTC+1, Nasser M. Abbasi wrote:
> On 2/18/2018 1:38 PM, Bojan Bozovic wrote:
> 
> If you are doing A*B by hand, then you are doing something
> wrong. Almost all languages end up calling Blas
> Fortran libraries for these operations. Your code and
> the Ada code can't be faster.
> 
> http://www.netlib.org/blas/
> 
> Intel Math Kernel Library has all these.
> 
> https://en.wikipedia.org/wiki/Math_Kernel_Library
> 
> --Nasser

Well I wanted to compare how Ada would do against C simply in 4x4 matrix multiplication, and I was surprised to see several times slower results, so I tried then to code 'by hand' to attempt to achieve the same speed with Ada (and the speed is comparable). I'm just learning the language and so I was unaware of it's finesses (such as making new instance of Ada.Numerics.Generic_Real_Arrays). Thanks for the links. I will have to bookmark them.


^ permalink raw reply	[relevance 11%]

* Re: GNAT can't vectorize Real_Matrix multiplication from Ada.Numerics.Real_Arrays. What a surprise!
  2018-02-18 19:38  5%         ` Bojan Bozovic
@ 2018-02-18 21:48  6%           ` Nasser M. Abbasi
  2018-02-18 22:50 11%             ` Bojan Bozovic
  2018-02-19 21:08  5%             ` Robert Eachus
  0 siblings, 2 replies; 200+ results
From: Nasser M. Abbasi @ 2018-02-18 21:48 UTC (permalink / raw)


On 2/18/2018 1:38 PM, Bojan Bozovic wrote:

If you are doing A*B by hand, then you are doing something
wrong. Almost all languages end up calling Blas
Fortran libraries for these operations. Your code and
the Ada code can't be faster.

http://www.netlib.org/blas/

Intel Math Kernel Library has all these.

https://en.wikipedia.org/wiki/Math_Kernel_Library

--Nasser


^ permalink raw reply	[relevance 6%]

* Re: GNAT can't vectorize Real_Matrix multiplication from Ada.Numerics.Real_Arrays. What a surprise!
  2018-02-18 13:31 12%       ` Jeffrey R. Carter
@ 2018-02-18 19:38  5%         ` Bojan Bozovic
  2018-02-18 21:48  6%           ` Nasser M. Abbasi
  0 siblings, 1 reply; 200+ results
From: Bojan Bozovic @ 2018-02-18 19:38 UTC (permalink / raw)


On Sunday, February 18, 2018 at 2:31:18 PM UTC+1, Jeffrey R. Carter wrote:
> On 02/18/2018 01:05 PM, Bojan Bozovic wrote:
> > Thanks very much for clarification! It's always good to learn something new, I suppose.
> 
> The real optimization in your example seems to be that the compiler optimizes 
> away the 10E6 loop around the in-line code, but not around the call to "*". 
> Removing both loops gives similar times for both multiplications. The call to 
> "*" will never be as fast because it copies its result into your variable. 
> Replacing Ada.Numerics.Real_Arrays with an instantiation of 
> Ada.Numerics.Generic_Real_Arrays gives an additional factor of 2 reduction.
> 
> -- 
> Jeff Carter
> Just as Khan was hindered by two-dimensional thinking in a
> three-dimensional situation, so many developers are hindered
> by sequential thinking in concurrent situations.
> 118

And indeed, now everything is in its place, as I don't see matrix multiplication several times slower than doing things 'by hand'. I have used aggressive optimization because in this day its custom a program to manipulate over gigabytes or even terabytes of data, while being at most megabytes in size - so compiling for various processors of the same family and using launcher program which will query processor capability and run optimally optimized program is nothing new - one might say most computation now is done on GPU but then also exact capabilities of GPU must be known. Thanks for making my Ada learning experience an enjoyment!

^ permalink raw reply	[relevance 5%]

* Re: GNAT can't vectorize Real_Matrix multiplication from Ada.Numerics.Real_Arrays. What a surprise!
  2018-02-18 12:05  6%     ` Bojan Bozovic
@ 2018-02-18 13:31 12%       ` Jeffrey R. Carter
  2018-02-18 19:38  5%         ` Bojan Bozovic
  0 siblings, 1 reply; 200+ results
From: Jeffrey R. Carter @ 2018-02-18 13:31 UTC (permalink / raw)


On 02/18/2018 01:05 PM, Bojan Bozovic wrote:
> Thanks very much for clarification! It's always good to learn something new, I suppose.

The real optimization in your example seems to be that the compiler optimizes 
away the 10E6 loop around the in-line code, but not around the call to "*". 
Removing both loops gives similar times for both multiplications. The call to 
"*" will never be as fast because it copies its result into your variable. 
Replacing Ada.Numerics.Real_Arrays with an instantiation of 
Ada.Numerics.Generic_Real_Arrays gives an additional factor of 2 reduction.

-- 
Jeff Carter
Just as Khan was hindered by two-dimensional thinking in a
three-dimensional situation, so many developers are hindered
by sequential thinking in concurrent situations.
118

^ permalink raw reply	[relevance 12%]

* Re: GNAT can't vectorize Real_Matrix multiplication from Ada.Numerics.Real_Arrays. What a surprise!
  2018-02-18 10:35 11%   ` Jeffrey R. Carter
@ 2018-02-18 12:05  6%     ` Bojan Bozovic
  2018-02-18 13:31 12%       ` Jeffrey R. Carter
  0 siblings, 1 reply; 200+ results
From: Bojan Bozovic @ 2018-02-18 12:05 UTC (permalink / raw)


Thanks very much for clarification! It's always good to learn something new, I suppose.

^ permalink raw reply	[relevance 6%]

* Re: GNAT can't vectorize Real_Matrix multiplication from Ada.Numerics.Real_Arrays. What a surprise!
  2018-02-18  1:51  9% ` Bojan Bozovic
@ 2018-02-18 10:35 11%   ` Jeffrey R. Carter
  2018-02-18 12:05  6%     ` Bojan Bozovic
  0 siblings, 1 reply; 200+ results
From: Jeffrey R. Carter @ 2018-02-18 10:35 UTC (permalink / raw)


On 02/18/2018 02:51 AM, Bojan Bozovic wrote:
> 
> Apart from response that they don't offer support on GPL versions of compiler, I got no response. I hope this will be useful to someone.

Nor should you expect anything to happen, since you have not found an error. An 
error is when the compiler accepts illegal code, rejects legal code, or produces 
object code that gives incorrect results. At best you have found an opportunity 
for better optimization. Even that seems unlikely.

Remember that Ada.Numerics.Real_Arrays."*" is a general-purpose library 
function. As such, it has to do things that your specific implementation of 
matrix multiplication doesn't: It has to check that Left'Length (2) = 
Right'Length (1) and raise an exception if they're not equal. Your code doesn't, 
and any such check should be optimized away because its condition will be 
statically False. The general code has to handle the case where Left'First (2) 
/= Right'First (1). Even when the offset is zero, that's still an extra addition 
in the inner loop.

Also, Ada.Numerics.Real_Arrays is provided precompiled, and is surely compiled 
with different optimization options than your code. (IIRC, -O3 is considered 
experimental, and AdaCore is not going to compile its library code with 
experimental optimization.)

You can find GNAT's implementation of matrix multiplication as 
System.Generic_Array_Operations.Matrix_Matrix_Product. This is extremely 
general, allowing for non-numeric matrix components (complex numbers, for 
example), and different component types for the left, right, and result 
matrices. This may introduce additional barriers to optimization.

Since Ada.Numerics.Real_Arrays is an instantiation of 
Ada.Numerics.Generic_Real_Arrays for Float, and GNAT does macro expansion of 
generics, if you use an explicit instantiation of 
Ada.Numerics.Generic_Real_Arrays in your code, it should be compiled with your 
compiler options and thus remove that variable from your comparison. Doing that 
in your code, and building with

gnatmake -O3 -mavx2 matrix_mul -largs -s

cuts the reported time for "*" by a factor of about 4. Not surprisingly, still 
slower. YMMV

-- 
Jeff Carter
Just as Khan was hindered by two-dimensional thinking in a
three-dimensional situation, so many developers are hindered
by sequential thinking in concurrent situations.
118

^ permalink raw reply	[relevance 11%]

* Re: GNAT can't vectorize Real_Matrix multiplication from Ada.Numerics.Real_Arrays. What a surprise!
  2018-02-17 12:55  7% GNAT can't vectorize Real_Matrix multiplication from Ada.Numerics.Real_Arrays. What a surprise! Bojan Bozovic
  2018-02-17 15:17  6% ` Bojan Bozovic
@ 2018-02-18  1:51  9% ` Bojan Bozovic
  2018-02-18 10:35 11%   ` Jeffrey R. Carter
  1 sibling, 1 reply; 200+ results
From: Bojan Bozovic @ 2018-02-18  1:51 UTC (permalink / raw)


On Saturday, February 17, 2018 at 1:55:49 PM UTC+1, Bojan Bozovic wrote:
> -- code
> 
> with Ada.Calendar;
> with Ada.Text_IO;
> with Ada.Numerics.Real_Arrays;
> use Ada.Calendar;
> use Ada.Text_IO;
> use Ada.Numerics.Real_Arrays;
> 
> procedure Matrix_Mul is
> 
>    package F_IO is new Ada.Text_IO.Fixed_IO (Day_Duration);
>    use F_IO;
> 
>    Start_Time, End_Time : Time;
> 
>    procedure Put (X : Real_Matrix) is
>    begin
>       for I in X'Range (1) loop
>          for J in X'Range (2) loop
>             Put (Float'Image (Float (X (I, J))));
>          end loop;
>          New_Line;
>       end loop;
>    end Put;
> 
>    Matrix_A, Matrix_B, Result : Real_Matrix (1 .. 4, 1 .. 4);
>    Elapsed_Time               : Duration;
>    Sum                        : Float;
> begin
>    Matrix_A :=
>      ((1.0, 1.0, 1.0, 1.0),
>       (2.0, 2.0, 2.0, 2.0),
>       (3.0, 3.0, 3.0, 3.0),
>       (4.0, 4.0, 4.0, 4.0));
>    Matrix_B :=
>      ((16.0, 15.0, 14.0, 13.0),
>       (12.0, 11.0, 10.0, 9.0),
>       (8.0, 7.0, 6.0, 5.0),
>       (4.0, 3.0, 2.0, 1.0));
> 
>    Start_Time := Clock;
>    for Iteration in 1 .. 10_000_000 loop
>       Result := Matrix_A * Matrix_B;
>    end loop;
>    End_Time     := Clock;
>    Elapsed_Time := End_Time - Start_Time;
>    Put (Result);
>    New_Line;
>    Put ("Elapsed Time is ");
>    Put (Elapsed_Time);
>    New_Line;
>    Start_Time := Clock;
>    for Iteration in 1 .. 10_000_000 loop
>       for I in Matrix_A'Range (1) loop
>          for J in Matrix_A'Range (2) loop
>             Sum := 0.0;
>             for K in Matrix_A'Range (2) loop
>                Sum := Sum + Matrix_A (I, K) * Matrix_B (K, J);
>             end loop;
>             Result (I, J) := Sum;
>          end loop;
>       end loop;
>    end loop;
>    End_Time     := Clock;
>    Elapsed_Time := End_Time - Start_Time;
>    Put (Result);
>    New_Line;
>    Put ("Elapsed time is ");
>    Put (Elapsed_Time);
>    New_Line;
> end Matrix_Mul;
> -- end code
> 
> Results: FSF GNAT 7.2.0 x64
> C:\Users\Bojan\Documents>gnatmake -O3 -fopt-info -march=skylake matrix_mul.adb -largs -s
> gcc -c -O3 -fopt-info -march=skylake matrix_mul.adb
> matrix_mul.adb:56:41: note: loop turned into non-loop; it never loops.
> matrix_mul.adb:56:41: note: loop with 4 iterations completely unrolled
> matrix_mul.adb:54:38: note: loop turned into non-loop; it never loops.
> matrix_mul.adb:54:38: note: loop with 4 iterations completely unrolled
> matrix_mul.adb:53:35: note: loop turned into non-loop; it never loops.
> matrix_mul.adb:53:35: note: loop with 4 iterations completely unrolled
> matrix_mul.adb:40:15: note: basic block vectorized
> matrix_mul.adb:42:26: note: basic block vectorized
> matrix_mul.adb:18:31: note: basic block vectorized
> matrix_mul.adb:49:9: note: basic block vectorized
> C:/MSYS64/MINGW64/lib/gcc/x86_64-w64-mingw32/7.2.0/adainclude/a-tifiio.adb:706:10: note: basic block vectorized
> matrix_mul.adb:64:17: note: basic block vectorized
> matrix_mul.adb:18:31: note: basic block vectorized
> matrix_mul.adb:68:9: note: basic block vectorized
> C:/MSYS64/MINGW64/lib/gcc/x86_64-w64-mingw32/7.2.0/adainclude/a-tifiio.adb:706:10: note: basic block vectorized
> gnatbind -x matrix_mul.ali
> gnatlink matrix_mul.ali -O3 -fopt-info -march=skylake -s
> 
> C:\Users\Bojan\Documents>matrix_mul
>  4.00000E+01 3.60000E+01 3.20000E+01 2.80000E+01
>  8.00000E+01 7.20000E+01 6.40000E+01 5.60000E+01
>  1.20000E+02 1.08000E+02 9.60000E+01 8.40000E+01
>  1.60000E+02 1.44000E+02 1.28000E+02 1.12000E+02
> 
> Elapsed Time is      1.338206667
>  4.00000E+01 3.60000E+01 3.20000E+01 2.80000E+01
>  8.00000E+01 7.20000E+01 6.40000E+01 5.60000E+01
>  1.20000E+02 1.08000E+02 9.60000E+01 8.40000E+01
>  1.60000E+02 1.44000E+02 1.28000E+02 1.12000E+02
> 
> Elapsed time is      0.000000445
> 
> C:\Users\Bojan\Documents>set path=C:\GNAT\2017\BIN;%path%
> 
> Results GPL GNAT/2017 from AdaCore.
> 
> C:\Users\Bojan\Documents>gnatmake -O3 -fopt-info -mavx2 matrix_mul.adb -largs -s
> gcc -c -O3 -fopt-info -mavx2 matrix_mul.adb
> matrix_mul.adb:56:41: note: loop turned into non-loop; it never loops.
> matrix_mul.adb:56:41: note: loop with 4 iterations completely unrolled
> matrix_mul.adb:54:38: note: loop turned into non-loop; it never loops.
> matrix_mul.adb:54:38: note: loop with 4 iterations completely unrolled
> matrix_mul.adb:53:35: note: loop turned into non-loop; it never loops.
> matrix_mul.adb:53:35: note: loop with 4 iterations completely unrolled
> matrix_mul.adb:40:15: note: basic block vectorized
> matrix_mul.adb:68:9: note: basic block vectorized
> gnatbind -x matrix_mul.ali
> gnatlink matrix_mul.ali -O3 -fopt-info -mavx2 -s
> 
> C:\Users\Bojan\Documents>matrix_mul
>  4.00000E+01 3.60000E+01 3.20000E+01 2.80000E+01
>  8.00000E+01 7.20000E+01 6.40000E+01 5.60000E+01
>  1.20000E+02 1.08000E+02 9.60000E+01 8.40000E+01
>  1.60000E+02 1.44000E+02 1.28000E+02 1.12000E+02
> 
> Elapsed Time is      2.145337334
>  4.00000E+01 3.60000E+01 3.20000E+01 2.80000E+01
>  8.00000E+01 7.20000E+01 6.40000E+01 5.60000E+01
>  1.20000E+02 1.08000E+02 9.60000E+01 8.40000E+01
>  1.60000E+02 1.44000E+02 1.28000E+02 1.12000E+02
> 
> Elapsed time is      0.000000444
> 
> C:\Users\Bojan\Documents>gcc --version
> gcc (GCC) 6.3.1 20170510 (for GNAT GPL 2017 20170515)
> Copyright (C) 2016 Free Software Foundation, Inc.
> This is free software; see the source for copying conditions.
> See your AdaCore support agreement for details of warranty and support.
> If you do not have a current support agreement, then there is absolutely
> no warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
> PURPOSE.
> 
> Should I submit this as bug to AdaCore? My computer is Intel Core i3-6100U (Skylake AVX2). Please try to reproduce.

Apart from response that they don't offer support on GPL versions of compiler, I got no response. I hope this will be useful to someone.

with Ada.Calendar;
with Ada.Text_IO;
with Ada.Numerics.Real_Arrays;
use Ada.Calendar;
use Ada.Text_IO;
use Ada.Numerics.Real_Arrays;

procedure Matrix_Mul is

   package F_IO is new Ada.Text_IO.Fixed_IO (Day_Duration);
   use F_IO;

   Start_Time, End_Time : Time;
   
   procedure Put (X : Real_Matrix) is
   begin
      for I in X'Range (1) loop
         for J in X'Range (2) loop
            Put (Float'Image (Float (X (I, J))));
         end loop;
         New_Line;
      end loop;
   end Put;


   Matrix_A, Matrix_B, Result : Real_Matrix (1 .. 4, 1 .. 4);
   Elapsed_Time               : Duration;
   Sum                        : Float;
   pragma Volatile (Matrix_A);
   pragma Volatile (Matrix_B);
   pragma Volatile (Result);
   Iterations : constant := 10_000_000;
begin
   Matrix_A :=
     ((1.0, 1.0, 1.0, 1.0),
      (2.0, 2.0, 2.0, 2.0),
      (3.0, 3.0, 3.0, 3.0),
      (4.0, 4.0, 4.0, 4.0));
   Matrix_B :=
     ((16.0, 15.0, 14.0, 13.0),
      (12.0, 11.0, 10.0, 9.0),
      (8.0, 7.0, 6.0, 5.0),
      (4.0, 3.0, 2.0, 1.0));

   Start_Time := Clock;
   for Iteration in 1..Iterations loop
      Result := Matrix_A * Matrix_B;
	end loop;
   End_Time     := Clock;
   Elapsed_Time := End_Time - Start_Time;
   Put (Result);
   New_Line;
   Put ("Elapsed Time is ");
   Put (Elapsed_Time);
   New_Line;
   Start_Time := Clock;
   for Iteration in 1 .. Iterations loop
   
      for I in Matrix_A'Range (1) loop
         for J in Matrix_A'Range (2) loop
            Sum := 0.0;
            for K in Matrix_A'Range (2) loop
               Sum := Sum + Matrix_A (I, K) * Matrix_B (K, J);
            end loop;
            Result (I, J) := Sum;
         end loop;
      end loop;
end loop;
   End_Time     := Clock;
   Elapsed_Time := End_Time - Start_Time;
   Put (Result);
   New_Line;
   Put ("Elapsed time is ");
   Put (Elapsed_Time);
   New_Line;
end Matrix_Mul;

-- end code

C:\Users\Bojan\Documents>gnatmake -O3 -mavx2 matrix_mul -largs -s
gcc -c -O3 -mavx2 matrix_mul.adb
gnatbind -x matrix_mul.ali
gnatlink matrix_mul.ali -O3 -mavx2 -s

C:\Users\Bojan\Documents>matrix_mul
 4.00000E+01 3.60000E+01 3.20000E+01 2.80000E+01
 8.00000E+01 7.20000E+01 6.40000E+01 5.60000E+01
 1.20000E+02 1.08000E+02 9.60000E+01 8.40000E+01
 1.60000E+02 1.44000E+02 1.28000E+02 1.12000E+02

Elapsed Time is      2.134868889
 4.00000E+01 3.60000E+01 3.20000E+01 2.80000E+01
 8.00000E+01 7.20000E+01 6.40000E+01 5.60000E+01
 1.20000E+02 1.08000E+02 9.60000E+01 8.40000E+01
 1.60000E+02 1.44000E+02 1.28000E+02 1.12000E+02

Elapsed time is      0.337315111

This is from GNAT/2017 compiler with these switches above.

^ permalink raw reply	[relevance 9%]

* Re: GNAT can't vectorize Real_Matrix multiplication from Ada.Numerics.Real_Arrays. What a surprise!
  2018-02-17 15:17  6% ` Bojan Bozovic
@ 2018-02-17 15:49  6%   ` Bojan Bozovic
  0 siblings, 0 replies; 200+ results
From: Bojan Bozovic @ 2018-02-17 15:49 UTC (permalink / raw)


On Saturday, February 17, 2018 at 4:17:41 PM UTC+1, Bojan Bozovic wrote:
> On Saturday, February 17, 2018 at 1:55:49 PM UTC+1, Bojan Bozovic wrote:
> > -- code
> > 
> > with Ada.Calendar;
> > with Ada.Text_IO;
> > with Ada.Numerics.Real_Arrays;
> > use Ada.Calendar;
> > use Ada.Text_IO;
> > use Ada.Numerics.Real_Arrays;
> > 
> > procedure Matrix_Mul is
> > 
> >    package F_IO is new Ada.Text_IO.Fixed_IO (Day_Duration);
> >    use F_IO;
> > 
> >    Start_Time, End_Time : Time;
> > 
> >    procedure Put (X : Real_Matrix) is
> >    begin
> >       for I in X'Range (1) loop
> >          for J in X'Range (2) loop
> >             Put (Float'Image (Float (X (I, J))));
> >          end loop;
> >          New_Line;
> >       end loop;
> >    end Put;
> > 
> >    Matrix_A, Matrix_B, Result : Real_Matrix (1 .. 4, 1 .. 4);
> >    Elapsed_Time               : Duration;
> >    Sum                        : Float;
> > begin
> >    Matrix_A :=
> >      ((1.0, 1.0, 1.0, 1.0),
> >       (2.0, 2.0, 2.0, 2.0),
> >       (3.0, 3.0, 3.0, 3.0),
> >       (4.0, 4.0, 4.0, 4.0));
> >    Matrix_B :=
> >      ((16.0, 15.0, 14.0, 13.0),
> >       (12.0, 11.0, 10.0, 9.0),
> >       (8.0, 7.0, 6.0, 5.0),
> >       (4.0, 3.0, 2.0, 1.0));
> > 
> >    Start_Time := Clock;
> >    for Iteration in 1 .. 10_000_000 loop
> >       Result := Matrix_A * Matrix_B;
> >    end loop;
> >    End_Time     := Clock;
> >    Elapsed_Time := End_Time - Start_Time;
> >    Put (Result);
> >    New_Line;
> >    Put ("Elapsed Time is ");
> >    Put (Elapsed_Time);
> >    New_Line;
> >    Start_Time := Clock;
> >    for Iteration in 1 .. 10_000_000 loop
> >       for I in Matrix_A'Range (1) loop
> >          for J in Matrix_A'Range (2) loop
> >             Sum := 0.0;
> >             for K in Matrix_A'Range (2) loop
> >                Sum := Sum + Matrix_A (I, K) * Matrix_B (K, J);
> >             end loop;
> >             Result (I, J) := Sum;
> >          end loop;
> >       end loop;
> >    end loop;
> >    End_Time     := Clock;
> >    Elapsed_Time := End_Time - Start_Time;
> >    Put (Result);
> >    New_Line;
> >    Put ("Elapsed time is ");
> >    Put (Elapsed_Time);
> >    New_Line;
> > end Matrix_Mul;
> > -- end code
> > 
> > Results: FSF GNAT 7.2.0 x64
> > C:\Users\Bojan\Documents>gnatmake -O3 -fopt-info -march=skylake matrix_mul.adb -largs -s
> > gcc -c -O3 -fopt-info -march=skylake matrix_mul.adb
> > matrix_mul.adb:56:41: note: loop turned into non-loop; it never loops.
> > matrix_mul.adb:56:41: note: loop with 4 iterations completely unrolled
> > matrix_mul.adb:54:38: note: loop turned into non-loop; it never loops.
> > matrix_mul.adb:54:38: note: loop with 4 iterations completely unrolled
> > matrix_mul.adb:53:35: note: loop turned into non-loop; it never loops.
> > matrix_mul.adb:53:35: note: loop with 4 iterations completely unrolled
> > matrix_mul.adb:40:15: note: basic block vectorized
> > matrix_mul.adb:42:26: note: basic block vectorized
> > matrix_mul.adb:18:31: note: basic block vectorized
> > matrix_mul.adb:49:9: note: basic block vectorized
> > C:/MSYS64/MINGW64/lib/gcc/x86_64-w64-mingw32/7.2.0/adainclude/a-tifiio.adb:706:10: note: basic block vectorized
> > matrix_mul.adb:64:17: note: basic block vectorized
> > matrix_mul.adb:18:31: note: basic block vectorized
> > matrix_mul.adb:68:9: note: basic block vectorized
> > C:/MSYS64/MINGW64/lib/gcc/x86_64-w64-mingw32/7.2.0/adainclude/a-tifiio.adb:706:10: note: basic block vectorized
> > gnatbind -x matrix_mul.ali
> > gnatlink matrix_mul.ali -O3 -fopt-info -march=skylake -s
> > 
> > C:\Users\Bojan\Documents>matrix_mul
> >  4.00000E+01 3.60000E+01 3.20000E+01 2.80000E+01
> >  8.00000E+01 7.20000E+01 6.40000E+01 5.60000E+01
> >  1.20000E+02 1.08000E+02 9.60000E+01 8.40000E+01
> >  1.60000E+02 1.44000E+02 1.28000E+02 1.12000E+02
> > 
> > Elapsed Time is      1.338206667
> >  4.00000E+01 3.60000E+01 3.20000E+01 2.80000E+01
> >  8.00000E+01 7.20000E+01 6.40000E+01 5.60000E+01
> >  1.20000E+02 1.08000E+02 9.60000E+01 8.40000E+01
> >  1.60000E+02 1.44000E+02 1.28000E+02 1.12000E+02
> > 
> > Elapsed time is      0.000000445
> > 
> > C:\Users\Bojan\Documents>set path=C:\GNAT\2017\BIN;%path%
> > 
> > Results GPL GNAT/2017 from AdaCore.
> > 
> > C:\Users\Bojan\Documents>gnatmake -O3 -fopt-info -mavx2 matrix_mul.adb -largs -s
> > gcc -c -O3 -fopt-info -mavx2 matrix_mul.adb
> > matrix_mul.adb:56:41: note: loop turned into non-loop; it never loops.
> > matrix_mul.adb:56:41: note: loop with 4 iterations completely unrolled
> > matrix_mul.adb:54:38: note: loop turned into non-loop; it never loops.
> > matrix_mul.adb:54:38: note: loop with 4 iterations completely unrolled
> > matrix_mul.adb:53:35: note: loop turned into non-loop; it never loops.
> > matrix_mul.adb:53:35: note: loop with 4 iterations completely unrolled
> > matrix_mul.adb:40:15: note: basic block vectorized
> > matrix_mul.adb:68:9: note: basic block vectorized
> > gnatbind -x matrix_mul.ali
> > gnatlink matrix_mul.ali -O3 -fopt-info -mavx2 -s
> > 
> > C:\Users\Bojan\Documents>matrix_mul
> >  4.00000E+01 3.60000E+01 3.20000E+01 2.80000E+01
> >  8.00000E+01 7.20000E+01 6.40000E+01 5.60000E+01
> >  1.20000E+02 1.08000E+02 9.60000E+01 8.40000E+01
> >  1.60000E+02 1.44000E+02 1.28000E+02 1.12000E+02
> > 
> > Elapsed Time is      2.145337334
> >  4.00000E+01 3.60000E+01 3.20000E+01 2.80000E+01
> >  8.00000E+01 7.20000E+01 6.40000E+01 5.60000E+01
> >  1.20000E+02 1.08000E+02 9.60000E+01 8.40000E+01
> >  1.60000E+02 1.44000E+02 1.28000E+02 1.12000E+02
> > 
> > Elapsed time is      0.000000444
> > 
> > C:\Users\Bojan\Documents>gcc --version
> > gcc (GCC) 6.3.1 20170510 (for GNAT GPL 2017 20170515)
> > Copyright (C) 2016 Free Software Foundation, Inc.
> > This is free software; see the source for copying conditions.
> > See your AdaCore support agreement for details of warranty and support.
> > If you do not have a current support agreement, then there is absolutely
> > no warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
> > PURPOSE.
> > 
> > Should I submit this as bug to AdaCore? My computer is Intel Core i3-6100U (Skylake AVX2). Please try to reproduce.
> 
> Compiler is smart enough to not iterate 10 million times over constant values, but there is still optimization problem.

I don't know how to use pragma Volatile to force  iterations, even though with no 10 million iterations but with single multiplication results are (from AdaCore GNAT/2017 GPL)

C:\Users\Bojan\Documents>matrix_mul
 4.00000E+01 3.60000E+01 3.20000E+01 2.80000E+01
 8.00000E+01 7.20000E+01 6.40000E+01 5.60000E+01
 1.20000E+02 1.08000E+02 9.60000E+01 8.40000E+01
 1.60000E+02 1.44000E+02 1.28000E+02 1.12000E+02

Elapsed Time is      0.000009333
 4.00000E+01 3.60000E+01 3.20000E+01 2.80000E+01
 8.00000E+01 7.20000E+01 6.40000E+01 5.60000E+01
 1.20000E+02 1.08000E+02 9.60000E+01 8.40000E+01
 1.60000E+02 1.44000E+02 1.28000E+02 1.12000E+02

Elapsed time is      0.000000889

I'm submitting this as bug to AdaCore.


^ permalink raw reply	[relevance 6%]

* Re: GNAT can't vectorize Real_Matrix multiplication from Ada.Numerics.Real_Arrays. What a surprise!
  2018-02-17 12:55  7% GNAT can't vectorize Real_Matrix multiplication from Ada.Numerics.Real_Arrays. What a surprise! Bojan Bozovic
@ 2018-02-17 15:17  6% ` Bojan Bozovic
  2018-02-17 15:49  6%   ` Bojan Bozovic
  2018-02-18  1:51  9% ` Bojan Bozovic
  1 sibling, 1 reply; 200+ results
From: Bojan Bozovic @ 2018-02-17 15:17 UTC (permalink / raw)


On Saturday, February 17, 2018 at 1:55:49 PM UTC+1, Bojan Bozovic wrote:
> -- code
> 
> with Ada.Calendar;
> with Ada.Text_IO;
> with Ada.Numerics.Real_Arrays;
> use Ada.Calendar;
> use Ada.Text_IO;
> use Ada.Numerics.Real_Arrays;
> 
> procedure Matrix_Mul is
> 
>    package F_IO is new Ada.Text_IO.Fixed_IO (Day_Duration);
>    use F_IO;
> 
>    Start_Time, End_Time : Time;
> 
>    procedure Put (X : Real_Matrix) is
>    begin
>       for I in X'Range (1) loop
>          for J in X'Range (2) loop
>             Put (Float'Image (Float (X (I, J))));
>          end loop;
>          New_Line;
>       end loop;
>    end Put;
> 
>    Matrix_A, Matrix_B, Result : Real_Matrix (1 .. 4, 1 .. 4);
>    Elapsed_Time               : Duration;
>    Sum                        : Float;
> begin
>    Matrix_A :=
>      ((1.0, 1.0, 1.0, 1.0),
>       (2.0, 2.0, 2.0, 2.0),
>       (3.0, 3.0, 3.0, 3.0),
>       (4.0, 4.0, 4.0, 4.0));
>    Matrix_B :=
>      ((16.0, 15.0, 14.0, 13.0),
>       (12.0, 11.0, 10.0, 9.0),
>       (8.0, 7.0, 6.0, 5.0),
>       (4.0, 3.0, 2.0, 1.0));
> 
>    Start_Time := Clock;
>    for Iteration in 1 .. 10_000_000 loop
>       Result := Matrix_A * Matrix_B;
>    end loop;
>    End_Time     := Clock;
>    Elapsed_Time := End_Time - Start_Time;
>    Put (Result);
>    New_Line;
>    Put ("Elapsed Time is ");
>    Put (Elapsed_Time);
>    New_Line;
>    Start_Time := Clock;
>    for Iteration in 1 .. 10_000_000 loop
>       for I in Matrix_A'Range (1) loop
>          for J in Matrix_A'Range (2) loop
>             Sum := 0.0;
>             for K in Matrix_A'Range (2) loop
>                Sum := Sum + Matrix_A (I, K) * Matrix_B (K, J);
>             end loop;
>             Result (I, J) := Sum;
>          end loop;
>       end loop;
>    end loop;
>    End_Time     := Clock;
>    Elapsed_Time := End_Time - Start_Time;
>    Put (Result);
>    New_Line;
>    Put ("Elapsed time is ");
>    Put (Elapsed_Time);
>    New_Line;
> end Matrix_Mul;
> -- end code
> 
> Results: FSF GNAT 7.2.0 x64
> C:\Users\Bojan\Documents>gnatmake -O3 -fopt-info -march=skylake matrix_mul.adb -largs -s
> gcc -c -O3 -fopt-info -march=skylake matrix_mul.adb
> matrix_mul.adb:56:41: note: loop turned into non-loop; it never loops.
> matrix_mul.adb:56:41: note: loop with 4 iterations completely unrolled
> matrix_mul.adb:54:38: note: loop turned into non-loop; it never loops.
> matrix_mul.adb:54:38: note: loop with 4 iterations completely unrolled
> matrix_mul.adb:53:35: note: loop turned into non-loop; it never loops.
> matrix_mul.adb:53:35: note: loop with 4 iterations completely unrolled
> matrix_mul.adb:40:15: note: basic block vectorized
> matrix_mul.adb:42:26: note: basic block vectorized
> matrix_mul.adb:18:31: note: basic block vectorized
> matrix_mul.adb:49:9: note: basic block vectorized
> C:/MSYS64/MINGW64/lib/gcc/x86_64-w64-mingw32/7.2.0/adainclude/a-tifiio.adb:706:10: note: basic block vectorized
> matrix_mul.adb:64:17: note: basic block vectorized
> matrix_mul.adb:18:31: note: basic block vectorized
> matrix_mul.adb:68:9: note: basic block vectorized
> C:/MSYS64/MINGW64/lib/gcc/x86_64-w64-mingw32/7.2.0/adainclude/a-tifiio.adb:706:10: note: basic block vectorized
> gnatbind -x matrix_mul.ali
> gnatlink matrix_mul.ali -O3 -fopt-info -march=skylake -s
> 
> C:\Users\Bojan\Documents>matrix_mul
>  4.00000E+01 3.60000E+01 3.20000E+01 2.80000E+01
>  8.00000E+01 7.20000E+01 6.40000E+01 5.60000E+01
>  1.20000E+02 1.08000E+02 9.60000E+01 8.40000E+01
>  1.60000E+02 1.44000E+02 1.28000E+02 1.12000E+02
> 
> Elapsed Time is      1.338206667
>  4.00000E+01 3.60000E+01 3.20000E+01 2.80000E+01
>  8.00000E+01 7.20000E+01 6.40000E+01 5.60000E+01
>  1.20000E+02 1.08000E+02 9.60000E+01 8.40000E+01
>  1.60000E+02 1.44000E+02 1.28000E+02 1.12000E+02
> 
> Elapsed time is      0.000000445
> 
> C:\Users\Bojan\Documents>set path=C:\GNAT\2017\BIN;%path%
> 
> Results GPL GNAT/2017 from AdaCore.
> 
> C:\Users\Bojan\Documents>gnatmake -O3 -fopt-info -mavx2 matrix_mul.adb -largs -s
> gcc -c -O3 -fopt-info -mavx2 matrix_mul.adb
> matrix_mul.adb:56:41: note: loop turned into non-loop; it never loops.
> matrix_mul.adb:56:41: note: loop with 4 iterations completely unrolled
> matrix_mul.adb:54:38: note: loop turned into non-loop; it never loops.
> matrix_mul.adb:54:38: note: loop with 4 iterations completely unrolled
> matrix_mul.adb:53:35: note: loop turned into non-loop; it never loops.
> matrix_mul.adb:53:35: note: loop with 4 iterations completely unrolled
> matrix_mul.adb:40:15: note: basic block vectorized
> matrix_mul.adb:68:9: note: basic block vectorized
> gnatbind -x matrix_mul.ali
> gnatlink matrix_mul.ali -O3 -fopt-info -mavx2 -s
> 
> C:\Users\Bojan\Documents>matrix_mul
>  4.00000E+01 3.60000E+01 3.20000E+01 2.80000E+01
>  8.00000E+01 7.20000E+01 6.40000E+01 5.60000E+01
>  1.20000E+02 1.08000E+02 9.60000E+01 8.40000E+01
>  1.60000E+02 1.44000E+02 1.28000E+02 1.12000E+02
> 
> Elapsed Time is      2.145337334
>  4.00000E+01 3.60000E+01 3.20000E+01 2.80000E+01
>  8.00000E+01 7.20000E+01 6.40000E+01 5.60000E+01
>  1.20000E+02 1.08000E+02 9.60000E+01 8.40000E+01
>  1.60000E+02 1.44000E+02 1.28000E+02 1.12000E+02
> 
> Elapsed time is      0.000000444
> 
> C:\Users\Bojan\Documents>gcc --version
> gcc (GCC) 6.3.1 20170510 (for GNAT GPL 2017 20170515)
> Copyright (C) 2016 Free Software Foundation, Inc.
> This is free software; see the source for copying conditions.
> See your AdaCore support agreement for details of warranty and support.
> If you do not have a current support agreement, then there is absolutely
> no warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
> PURPOSE.
> 
> Should I submit this as bug to AdaCore? My computer is Intel Core i3-6100U (Skylake AVX2). Please try to reproduce.

Compiler is smart enough to not iterate 10 million times over constant values, but there is still optimization problem.


^ permalink raw reply	[relevance 6%]

* GNAT can't vectorize Real_Matrix multiplication from Ada.Numerics.Real_Arrays. What a surprise!
@ 2018-02-17 12:55  7% Bojan Bozovic
  2018-02-17 15:17  6% ` Bojan Bozovic
  2018-02-18  1:51  9% ` Bojan Bozovic
  0 siblings, 2 replies; 200+ results
From: Bojan Bozovic @ 2018-02-17 12:55 UTC (permalink / raw)


-- code

with Ada.Calendar;
with Ada.Text_IO;
with Ada.Numerics.Real_Arrays;
use Ada.Calendar;
use Ada.Text_IO;
use Ada.Numerics.Real_Arrays;

procedure Matrix_Mul is

   package F_IO is new Ada.Text_IO.Fixed_IO (Day_Duration);
   use F_IO;

   Start_Time, End_Time : Time;

   procedure Put (X : Real_Matrix) is
   begin
      for I in X'Range (1) loop
         for J in X'Range (2) loop
            Put (Float'Image (Float (X (I, J))));
         end loop;
         New_Line;
      end loop;
   end Put;

   Matrix_A, Matrix_B, Result : Real_Matrix (1 .. 4, 1 .. 4);
   Elapsed_Time               : Duration;
   Sum                        : Float;
begin
   Matrix_A :=
     ((1.0, 1.0, 1.0, 1.0),
      (2.0, 2.0, 2.0, 2.0),
      (3.0, 3.0, 3.0, 3.0),
      (4.0, 4.0, 4.0, 4.0));
   Matrix_B :=
     ((16.0, 15.0, 14.0, 13.0),
      (12.0, 11.0, 10.0, 9.0),
      (8.0, 7.0, 6.0, 5.0),
      (4.0, 3.0, 2.0, 1.0));

   Start_Time := Clock;
   for Iteration in 1 .. 10_000_000 loop
      Result := Matrix_A * Matrix_B;
   end loop;
   End_Time     := Clock;
   Elapsed_Time := End_Time - Start_Time;
   Put (Result);
   New_Line;
   Put ("Elapsed Time is ");
   Put (Elapsed_Time);
   New_Line;
   Start_Time := Clock;
   for Iteration in 1 .. 10_000_000 loop
      for I in Matrix_A'Range (1) loop
         for J in Matrix_A'Range (2) loop
            Sum := 0.0;
            for K in Matrix_A'Range (2) loop
               Sum := Sum + Matrix_A (I, K) * Matrix_B (K, J);
            end loop;
            Result (I, J) := Sum;
         end loop;
      end loop;
   end loop;
   End_Time     := Clock;
   Elapsed_Time := End_Time - Start_Time;
   Put (Result);
   New_Line;
   Put ("Elapsed time is ");
   Put (Elapsed_Time);
   New_Line;
end Matrix_Mul;
-- end code

Results: FSF GNAT 7.2.0 x64
C:\Users\Bojan\Documents>gnatmake -O3 -fopt-info -march=skylake matrix_mul.adb -largs -s
gcc -c -O3 -fopt-info -march=skylake matrix_mul.adb
matrix_mul.adb:56:41: note: loop turned into non-loop; it never loops.
matrix_mul.adb:56:41: note: loop with 4 iterations completely unrolled
matrix_mul.adb:54:38: note: loop turned into non-loop; it never loops.
matrix_mul.adb:54:38: note: loop with 4 iterations completely unrolled
matrix_mul.adb:53:35: note: loop turned into non-loop; it never loops.
matrix_mul.adb:53:35: note: loop with 4 iterations completely unrolled
matrix_mul.adb:40:15: note: basic block vectorized
matrix_mul.adb:42:26: note: basic block vectorized
matrix_mul.adb:18:31: note: basic block vectorized
matrix_mul.adb:49:9: note: basic block vectorized
C:/MSYS64/MINGW64/lib/gcc/x86_64-w64-mingw32/7.2.0/adainclude/a-tifiio.adb:706:10: note: basic block vectorized
matrix_mul.adb:64:17: note: basic block vectorized
matrix_mul.adb:18:31: note: basic block vectorized
matrix_mul.adb:68:9: note: basic block vectorized
C:/MSYS64/MINGW64/lib/gcc/x86_64-w64-mingw32/7.2.0/adainclude/a-tifiio.adb:706:10: note: basic block vectorized
gnatbind -x matrix_mul.ali
gnatlink matrix_mul.ali -O3 -fopt-info -march=skylake -s

C:\Users\Bojan\Documents>matrix_mul
 4.00000E+01 3.60000E+01 3.20000E+01 2.80000E+01
 8.00000E+01 7.20000E+01 6.40000E+01 5.60000E+01
 1.20000E+02 1.08000E+02 9.60000E+01 8.40000E+01
 1.60000E+02 1.44000E+02 1.28000E+02 1.12000E+02

Elapsed Time is      1.338206667
 4.00000E+01 3.60000E+01 3.20000E+01 2.80000E+01
 8.00000E+01 7.20000E+01 6.40000E+01 5.60000E+01
 1.20000E+02 1.08000E+02 9.60000E+01 8.40000E+01
 1.60000E+02 1.44000E+02 1.28000E+02 1.12000E+02

Elapsed time is      0.000000445

C:\Users\Bojan\Documents>set path=C:\GNAT\2017\BIN;%path%

Results GPL GNAT/2017 from AdaCore.

C:\Users\Bojan\Documents>gnatmake -O3 -fopt-info -mavx2 matrix_mul.adb -largs -s
gcc -c -O3 -fopt-info -mavx2 matrix_mul.adb
matrix_mul.adb:56:41: note: loop turned into non-loop; it never loops.
matrix_mul.adb:56:41: note: loop with 4 iterations completely unrolled
matrix_mul.adb:54:38: note: loop turned into non-loop; it never loops.
matrix_mul.adb:54:38: note: loop with 4 iterations completely unrolled
matrix_mul.adb:53:35: note: loop turned into non-loop; it never loops.
matrix_mul.adb:53:35: note: loop with 4 iterations completely unrolled
matrix_mul.adb:40:15: note: basic block vectorized
matrix_mul.adb:68:9: note: basic block vectorized
gnatbind -x matrix_mul.ali
gnatlink matrix_mul.ali -O3 -fopt-info -mavx2 -s

C:\Users\Bojan\Documents>matrix_mul
 4.00000E+01 3.60000E+01 3.20000E+01 2.80000E+01
 8.00000E+01 7.20000E+01 6.40000E+01 5.60000E+01
 1.20000E+02 1.08000E+02 9.60000E+01 8.40000E+01
 1.60000E+02 1.44000E+02 1.28000E+02 1.12000E+02

Elapsed Time is      2.145337334
 4.00000E+01 3.60000E+01 3.20000E+01 2.80000E+01
 8.00000E+01 7.20000E+01 6.40000E+01 5.60000E+01
 1.20000E+02 1.08000E+02 9.60000E+01 8.40000E+01
 1.60000E+02 1.44000E+02 1.28000E+02 1.12000E+02

Elapsed time is      0.000000444

C:\Users\Bojan\Documents>gcc --version
gcc (GCC) 6.3.1 20170510 (for GNAT GPL 2017 20170515)
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
See your AdaCore support agreement for details of warranty and support.
If you do not have a current support agreement, then there is absolutely
no warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.

Should I submit this as bug to AdaCore? My computer is Intel Core i3-6100U (Skylake AVX2). Please try to reproduce.


^ permalink raw reply	[relevance 7%]

* Re: Generic_Rational
  2018-02-17 11:52  5% Generic_Rational hnptz
@ 2018-02-17 12:33  0% ` Simon Wright
  0 siblings, 0 replies; 200+ results
From: Simon Wright @ 2018-02-17 12:33 UTC (permalink / raw)


hnptz@yahoo.de writes:

> On http://rosettacode.org/wiki/Arithmetic/Rational/Ada there is an
> Ada-package which is OK as it is. It says that the package can be
> instantiated with any integer type. However, I tried to instantiate it
> with Long_Integer.

And the instantiation compiles fine.

> I also used Ada.Numerics.Long_Elementary_Functions. 

There was no need for that.

> Now, the Test_Rational programm does not work anymore. The function
> "/" is perhaps not in compliance with Long_Integer. I wonder if the
> declarative part in Test_Rational has a false effect.
>
> What are your suggestions to make it working for Long_Integer numbers
> as well?

When the test program says

   for Candidate in 2..2**15 loop

Candidate is of type Integer (see ARM 3.6(17..18)[1], so that when it
says

         Sum  : Rational := 1 / Candidate;

there would need to be a function

   function "/" (L, R : Integer) return Rational

but the only "/" that returns Rational and takes integer types takes
Long_Integers.

Recast the loop as

   for Candidate in Long_Integer'(2)..2**15 loop

or

   for Candidate in Long_Integer range 2..2**15 loop

and now there's a similar problem with

         for Divisor in 2..Integer (Sqrt (Float (Candidate))) loop

...

[1] http://www.ada-auth.org/standards/rm12_w_tc1/html/RM-3-6.html#p17


^ permalink raw reply	[relevance 0%]

* Generic_Rational
@ 2018-02-17 11:52  5% hnptz
  2018-02-17 12:33  0% ` Generic_Rational Simon Wright
  0 siblings, 1 reply; 200+ results
From: hnptz @ 2018-02-17 11:52 UTC (permalink / raw)


On http://rosettacode.org/wiki/Arithmetic/Rational/Ada there is an Ada-package which is OK as it is. It says that the package can be instantiated with any integer type. However, I tried to instantiate it with Long_Integer.
I also used Ada.Numerics.Long_Elementary_Functions. 

Now, the Test_Rational programm does not work anymore. The function "/" is perhaps not in compliance with Long_Integer. I wonder if the declarative part in Test_Rational has a false effect.

What are your suggestions to make it working for Long_Integer numbers as well?

best,

montgrimpulo
 


^ permalink raw reply	[relevance 5%]

* Re: Array of records with default values not propagating to array
  2018-02-03 11:06  5% Array of records with default values not propagating to array Bojan Bozovic
  2018-02-03 14:16  4% ` Jere
  2018-02-04  4:59  0% ` Bojan Bozovic
@ 2018-02-04 10:19  0% ` Jeffrey R. Carter
  2 siblings, 0 replies; 200+ results
From: Jeffrey R. Carter @ 2018-02-04 10:19 UTC (permalink / raw)


On 02/03/2018 12:06 PM, Bojan Bozovic wrote:
> When I defined a record, and set a default value for some of its components, these don't propagate when I make array of these records. Here is code that can be compiled, but I wonder do I need to explicitly assign value for 'others' in 'Initialize' procedure. This has nothing to do with Ada random number generation, I might have as well used Ada.Numerics.Float_Random, or the reusable code that was posted in another thread, with the same result, so I will post in this separate thread. When I omit "others =>" in Initialize, I get compilation errors at these lines both on FSF compiler and AdaCore GPL compiler on Windows. Is this intended behavior or I am missing something?

I'm not sure what you're experiencing. Your code, as given, compiles and works 
fine for me.

-- 
Jeff Carter
"I like it when the support group complains that they have
insufficient data on mean time to repair bugs in Ada software."
Robert I. Eachus
91


^ permalink raw reply	[relevance 0%]

* Re: Array of records with default values not propagating to array
  2018-02-03 11:06  5% Array of records with default values not propagating to array Bojan Bozovic
  2018-02-03 14:16  4% ` Jere
@ 2018-02-04  4:59  0% ` Bojan Bozovic
  2018-02-04 10:19  0% ` Jeffrey R. Carter
  2 siblings, 0 replies; 200+ results
From: Bojan Bozovic @ 2018-02-04  4:59 UTC (permalink / raw)


On Saturday, February 3, 2018 at 12:06:52 PM UTC+1, Bojan Bozovic wrote:
> When I defined a record, and set a default value for some of its components, these don't propagate when I make array of these records. Here is code that can be compiled, but I wonder do I need to explicitly assign value for 'others' in 'Initialize' procedure. This has nothing to do with Ada random number generation, I might have as well used Ada.Numerics.Float_Random, or the reusable code that was posted in another thread, with the same result, so I will post in this separate thread. When I omit "others =>" in Initialize, I get compilation errors at these lines both on FSF compiler and AdaCore GPL compiler on Windows. Is this intended behavior or I am missing something?
> 
> with Ada.Numerics.Discrete_Random;
> with Ada.Text_IO;
> with Ada.Text_IO.Unbounded_IO;
> with Ada.Strings;
> with Ada.Strings.Unbounded;
> 
> procedure Tarot1 is
> 
> Maximum_Deck_Length: constant integer := 78;
> subtype Card_Position is Positive range 1..Maximum_Deck_Length;
> type Card_Suits is (Cups,Pentacles,Swords,Wands);
> type Trump_Values is new Natural range 0..21;
> type Card_Values is (Two,Three,Four,Five,Six,Seven,Eight,Nine,Ten,Page,Knight,Queen,King,Ace);
> type Card_Info (Trump: Boolean := False) is record
> -- we will skip giving name and divinatory meaning to cards - its just ordinary assignment but for each card separately;
> -- PROBLEM: Assignment here does nothing, so I have to assign these values in Initialize procedure below as well
> 
> Name : Ada.Strings.Unbounded.Unbounded_String := Ada.Strings.Unbounded.Null_Unbounded_String;
> Divinatory_Meaning: Ada.Strings.Unbounded.Unbounded_String := Ada.Strings.Unbounded.Null_Unbounded_String;
> 
> case Trump is 
> 	when True => Trump_Value:Trump_Values;
> 	when False =>  Card_Value:Card_Values;
> 					Suit_Value:Card_Suits;
> end case;
> end record;
> type Deck is array (Card_Position) of Card_Info;
> package Card_Position_Random is new Ada.Numerics.Discrete_Random (Result_Subtype => Card_Position);
> 
> procedure Initialize ( TDeck : in out Deck) is
> 	Index: Card_Position := 1;
> 	begin
> 		-- first lay 22 trump cards in a deck
> 			for Index_1 in Trump_Values loop
> 			TDeck (Index) := (Trump => True, Trump_Value => Index_1, others => Ada.Strings.Unbounded.Null_Unbounded_String);
> 			Index := Index + 1;
> 			end loop;
> 		-- now lay 4 suits of 14 cards each;
> 		for Suit_Index in Card_Suits loop
> 			for Card_Index in Card_Values loop
> 			TDeck (Index) := (Trump => False, Card_Value => Card_Index, Suit_Value => Suit_Index, others => Ada.Strings.Unbounded.Null_Unbounded_String);
> 			exit when Index=Maximum_Deck_Length; -- preventing CONSTRAINT_ERROR;
> 			Index:=Index+1;
> 			end loop;
> 			end loop;
> end Initialize;
> 
>    procedure Shuffle (TDeck : in out Deck) is
>       Position_Gen   : Card_Position_Random.Generator;
>       Temporary_Data : Card_Info;
>       Index_Random   : Card_Position;
>    begin
>       Card_Position_Random.Reset (Gen => Position_Gen);
>       for Index in Card_Position loop
>          Index_Random         := Card_Position_Random.Random (Gen => Position_Gen);
>          Temporary_Data       := TDeck (Index);
>          TDeck (Index)        := TDeck (Index_Random);
>          TDeck (Index_Random) := Temporary_Data;
>       end loop;
>    end Shuffle;
>    Tarot_Deck : Deck;
>    begin
>    Initialize(Tarot_Deck);
>    Shuffle(Tarot_Deck);
>    for Index in Card_Position loop -- just print the deck as shuffled
>    if Tarot_Deck(Index).Trump then
> 	Ada.Text_IO.Put_Line("Major Arcana/Trump: "&Trump_Values'Image(Tarot_Deck(Index).Trump_Value));
> else
> 	Ada.Text_IO.Put_Line("Minor Arcana: "&Card_Values'Image(Tarot_Deck(Index).Card_Value)&" of "&Card_Suits'Image(Tarot_Deck(Index).Suit_Value));
> 	end if;
> 	end loop;
>    end Tarot1;
> 
> Thanks for help.

The compiler does compile assignment of others => <> to uninitialized record components as Mr. Simon Wright noticed above, I have reproduced the bug both with GNAT 2017 GPL and FSF GNAT on Cygwin (6.4.0), problem is I don't have GNAT Pro subscription for access to AdaCore GNAT tracker, and I can't open an account on GCC Bugzilla either, as my mail to administration is rejected and direct account creation is disabled. We can only hope that powers that be take notice of this. Thanks for the suggestions by the way.


^ permalink raw reply	[relevance 0%]

* Re: Array of records with default values not propagating to array
  2018-02-03 11:06  5% Array of records with default values not propagating to array Bojan Bozovic
@ 2018-02-03 14:16  4% ` Jere
  2018-02-04  4:59  0% ` Bojan Bozovic
  2018-02-04 10:19  0% ` Jeffrey R. Carter
  2 siblings, 0 replies; 200+ results
From: Jere @ 2018-02-03 14:16 UTC (permalink / raw)


On Saturday, February 3, 2018 at 6:06:52 AM UTC-5, Bojan Bozovic wrote:
> When I defined a record, and set a default value for some of its components, these don't propagate when I make array of these records. Here is code that can be compiled, but I wonder do I need to explicitly assign value for 'others' in 'Initialize' procedure. This has nothing to do with Ada random number generation, I might have as well used Ada.Numerics.Float_Random, or the reusable code that was posted in another thread, with the same result, so I will post in this separate thread. When I omit "others =>" in Initialize, I get compilation errors at these lines both on FSF compiler and AdaCore GPL compiler on Windows. Is this intended behavior or I am missing something?
> 
> with Ada.Numerics.Discrete_Random;
> with Ada.Text_IO;
> with Ada.Text_IO.Unbounded_IO;
> with Ada.Strings;
> with Ada.Strings.Unbounded;
> 
> procedure Tarot1 is
> 
> Maximum_Deck_Length: constant integer := 78;
> subtype Card_Position is Positive range 1..Maximum_Deck_Length;
> type Card_Suits is (Cups,Pentacles,Swords,Wands);
> type Trump_Values is new Natural range 0..21;
> type Card_Values is (Two,Three,Four,Five,Six,Seven,Eight,Nine,Ten,Page,Knight,Queen,King,Ace);
> type Card_Info (Trump: Boolean := False) is record
> -- we will skip giving name and divinatory meaning to cards - its just ordinary assignment but for each card separately;
> -- PROBLEM: Assignment here does nothing, so I have to assign these values in Initialize procedure below as well
> 
> Name : Ada.Strings.Unbounded.Unbounded_String := Ada.Strings.Unbounded.Null_Unbounded_String;
> Divinatory_Meaning: Ada.Strings.Unbounded.Unbounded_String := Ada.Strings.Unbounded.Null_Unbounded_String;
> 
> case Trump is 
> 	when True => Trump_Value:Trump_Values;
> 	when False =>  Card_Value:Card_Values;
> 					Suit_Value:Card_Suits;
> end case;
> end record;
> type Deck is array (Card_Position) of Card_Info;
> package Card_Position_Random is new Ada.Numerics.Discrete_Random (Result_Subtype => Card_Position);
> 
> procedure Initialize ( TDeck : in out Deck) is
> 	Index: Card_Position := 1;
> 	begin
> 		-- first lay 22 trump cards in a deck
> 			for Index_1 in Trump_Values loop
> 			TDeck (Index) := (Trump => True, Trump_Value => Index_1, others => Ada.Strings.Unbounded.Null_Unbounded_String);
> 			Index := Index + 1;
> 			end loop;
> 		-- now lay 4 suits of 14 cards each;
> 		for Suit_Index in Card_Suits loop
> 			for Card_Index in Card_Values loop
> 			TDeck (Index) := (Trump => False, Card_Value => Card_Index, Suit_Value => Suit_Index, others => Ada.Strings.Unbounded.Null_Unbounded_String);
> 			exit when Index=Maximum_Deck_Length; -- preventing CONSTRAINT_ERROR;
> 			Index:=Index+1;
> 			end loop;
> 			end loop;
> end Initialize;
> 
>    procedure Shuffle (TDeck : in out Deck) is
>       Position_Gen   : Card_Position_Random.Generator;
>       Temporary_Data : Card_Info;
>       Index_Random   : Card_Position;
>    begin
>       Card_Position_Random.Reset (Gen => Position_Gen);
>       for Index in Card_Position loop
>          Index_Random         := Card_Position_Random.Random (Gen => Position_Gen);
>          Temporary_Data       := TDeck (Index);
>          TDeck (Index)        := TDeck (Index_Random);
>          TDeck (Index_Random) := Temporary_Data;
>       end loop;
>    end Shuffle;
>    Tarot_Deck : Deck;
>    begin
>    Initialize(Tarot_Deck);
>    Shuffle(Tarot_Deck);
>    for Index in Card_Position loop -- just print the deck as shuffled
>    if Tarot_Deck(Index).Trump then
> 	Ada.Text_IO.Put_Line("Major Arcana/Trump: "&Trump_Values'Image(Tarot_Deck(Index).Trump_Value));
> else
> 	Ada.Text_IO.Put_Line("Minor Arcana: "&Card_Values'Image(Tarot_Deck(Index).Card_Value)&" of "&Card_Suits'Image(Tarot_Deck(Index).Suit_Value));
> 	end if;
> 	end loop;
>    end Tarot1;
> 
> Thanks for help.

The big issue I see is not incrementing Index in the first loop.  As it
stands, you simply keep reassigning trumps to the same card over and over
again.  Since the type is uninitialized and the next for loop cannot fill
the deck, you get a constraint error later on in the print statement when
trying to print a minor arcana.  As a note, defaulting the variant portion
of the record definition did prevent the constraint error, though obviously
the results were wrong because Initialize did not initialize the whole deck.

Try:

with Ada.Numerics.Discrete_Random;
with Ada.Text_IO;
with Ada.Text_IO.Unbounded_IO;
with Ada.Strings;
with Ada.Strings.Unbounded; 

procedure Tarot1 is
   
   Maximum_Deck_Length: constant integer := 78;
   subtype Card_Position is Positive range 1..Maximum_Deck_Length;
   type Card_Suits is (Cups,Pentacles,Swords,Wands);
   type Trump_Values is new Natural range 0..21;
   type Card_Values is (Two,Three,Four,Five,Six,Seven,Eight,Nine,Ten,Page,Knight,Queen,King,Ace);
   type Card_Info (Trump: Boolean := False) is record
      -- we will skip giving name and divinatory meaning to cards - its just ordinary assignment but for each card separately;
      -- PROBLEM: Assignment here does nothing, so I have to assign these values in Initialize procedure below as well

      Name : Ada.Strings.Unbounded.Unbounded_String := Ada.Strings.Unbounded.Null_Unbounded_String;
      Divinatory_Meaning: Ada.Strings.Unbounded.Unbounded_String := Ada.Strings.Unbounded.Null_Unbounded_String;

      case Trump is
         when True =>
            Trump_Value:Trump_Values;
         when False =>
            Card_Value:Card_Values;
            Suit_Value:Card_Suits;
      end case;
   end record;
   type Deck is array (Card_Position) of Card_Info;
   package Card_Position_Random is new Ada.Numerics.Discrete_Random (Result_Subtype => Card_Position);

   procedure Initialize ( TDeck : in out Deck) is
      Index: Card_Position := 1;
   begin
      -- first lay 22 trump cards in a deck
      for Index_1 in Trump_Values loop
         TDeck (Index) := (Trump => True, Trump_Value => Index_1, others => <>);
         Index := Index + 1;  -- Jere:  I added this
      end loop;
      
      -- now lay 4 suits of 14 cards each;
      for Suit_Index in Card_Suits loop
         for Card_Index in Card_Values loop
            TDeck (Index) := (Trump => False, Card_Value => Card_Index, Suit_Value => Suit_Index, others => <>);
            exit when Index=Maximum_Deck_Length; -- preventing CONSTRAINT_ERROR;
            Index:=Index+1;
         end loop;
      end loop;
   end Initialize;

   procedure Shuffle (TDeck : in out Deck) is
      Position_Gen   : Card_Position_Random.Generator;
      Temporary_Data : Card_Info;
      Index_Random   : Card_Position;
   begin
      Card_Position_Random.Reset (Gen => Position_Gen);
      for Index in Card_Position loop
         Index_Random         := Card_Position_Random.Random (Gen => Position_Gen);
         Temporary_Data       := TDeck (Index);
         TDeck (Index)        := TDeck (Index_Random);
         TDeck (Index_Random) := Temporary_Data;
      end loop;
   end Shuffle;
   Tarot_Deck : Deck; 
   
begin
   
   Initialize(Tarot_Deck);
   Shuffle(Tarot_Deck);
   for Index in Card_Position loop -- just print the deck as shuffled
      Ada.Text_IO.put("Index = " & Card_Position'Image(Index) & " => ");
      if Tarot_Deck(Index).Trump then
         Ada.Text_IO.Put_Line("Major Arcana/Trump: "&Trump_Values'Image(Tarot_Deck(Index).Trump_Value));
      else
         Ada.Text_IO.Put_Line("Minor Arcana: "&Card_Values'Image(Tarot_Deck(Index).Card_Value)&" of "&Card_Suits'Image(Tarot_Deck(Index).Suit_Value));
      end if;
   end loop;
   
end Tarot1;

^ permalink raw reply	[relevance 4%]

* Array of records with default values not propagating to array
@ 2018-02-03 11:06  5% Bojan Bozovic
  2018-02-03 14:16  4% ` Jere
                   ` (2 more replies)
  0 siblings, 3 replies; 200+ results
From: Bojan Bozovic @ 2018-02-03 11:06 UTC (permalink / raw)


When I defined a record, and set a default value for some of its components, these don't propagate when I make array of these records. Here is code that can be compiled, but I wonder do I need to explicitly assign value for 'others' in 'Initialize' procedure. This has nothing to do with Ada random number generation, I might have as well used Ada.Numerics.Float_Random, or the reusable code that was posted in another thread, with the same result, so I will post in this separate thread. When I omit "others =>" in Initialize, I get compilation errors at these lines both on FSF compiler and AdaCore GPL compiler on Windows. Is this intended behavior or I am missing something?

with Ada.Numerics.Discrete_Random;
with Ada.Text_IO;
with Ada.Text_IO.Unbounded_IO;
with Ada.Strings;
with Ada.Strings.Unbounded;

procedure Tarot1 is

Maximum_Deck_Length: constant integer := 78;
subtype Card_Position is Positive range 1..Maximum_Deck_Length;
type Card_Suits is (Cups,Pentacles,Swords,Wands);
type Trump_Values is new Natural range 0..21;
type Card_Values is (Two,Three,Four,Five,Six,Seven,Eight,Nine,Ten,Page,Knight,Queen,King,Ace);
type Card_Info (Trump: Boolean := False) is record
-- we will skip giving name and divinatory meaning to cards - its just ordinary assignment but for each card separately;
-- PROBLEM: Assignment here does nothing, so I have to assign these values in Initialize procedure below as well

Name : Ada.Strings.Unbounded.Unbounded_String := Ada.Strings.Unbounded.Null_Unbounded_String;
Divinatory_Meaning: Ada.Strings.Unbounded.Unbounded_String := Ada.Strings.Unbounded.Null_Unbounded_String;

case Trump is 
	when True => Trump_Value:Trump_Values;
	when False =>  Card_Value:Card_Values;
					Suit_Value:Card_Suits;
end case;
end record;
type Deck is array (Card_Position) of Card_Info;
package Card_Position_Random is new Ada.Numerics.Discrete_Random (Result_Subtype => Card_Position);

procedure Initialize ( TDeck : in out Deck) is
	Index: Card_Position := 1;
	begin
		-- first lay 22 trump cards in a deck
			for Index_1 in Trump_Values loop
			TDeck (Index) := (Trump => True, Trump_Value => Index_1, others => Ada.Strings.Unbounded.Null_Unbounded_String);
			Index := Index + 1;
			end loop;
		-- now lay 4 suits of 14 cards each;
		for Suit_Index in Card_Suits loop
			for Card_Index in Card_Values loop
			TDeck (Index) := (Trump => False, Card_Value => Card_Index, Suit_Value => Suit_Index, others => Ada.Strings.Unbounded.Null_Unbounded_String);
			exit when Index=Maximum_Deck_Length; -- preventing CONSTRAINT_ERROR;
			Index:=Index+1;
			end loop;
			end loop;
end Initialize;

   procedure Shuffle (TDeck : in out Deck) is
      Position_Gen   : Card_Position_Random.Generator;
      Temporary_Data : Card_Info;
      Index_Random   : Card_Position;
   begin
      Card_Position_Random.Reset (Gen => Position_Gen);
      for Index in Card_Position loop
         Index_Random         := Card_Position_Random.Random (Gen => Position_Gen);
         Temporary_Data       := TDeck (Index);
         TDeck (Index)        := TDeck (Index_Random);
         TDeck (Index_Random) := Temporary_Data;
      end loop;
   end Shuffle;
   Tarot_Deck : Deck;
   begin
   Initialize(Tarot_Deck);
   Shuffle(Tarot_Deck);
   for Index in Card_Position loop -- just print the deck as shuffled
   if Tarot_Deck(Index).Trump then
	Ada.Text_IO.Put_Line("Major Arcana/Trump: "&Trump_Values'Image(Tarot_Deck(Index).Trump_Value));
else
	Ada.Text_IO.Put_Line("Minor Arcana: "&Card_Values'Image(Tarot_Deck(Index).Card_Value)&" of "&Card_Suits'Image(Tarot_Deck(Index).Suit_Value));
	end if;
	end loop;
   end Tarot1;

Thanks for help.



^ permalink raw reply	[relevance 5%]

* Re: Card game deck but with trumps suit for tarot "divination" Is there a better way than enumerating all cards?
  2018-01-28  8:57  0% ` Jacob Sparre Andersen
@ 2018-01-28  9:23  0%   ` bozovic.bojan
  0 siblings, 0 replies; 200+ results
From: bozovic.bojan @ 2018-01-28  9:23 UTC (permalink / raw)


On Sunday, January 28, 2018 at 9:57:34 AM UTC+1, Jacob Sparre Andersen wrote:
> bozovic.bojan@gmail.com writes:
> 
> > These cards contain of 4 suits of 14 cards each, and special "trump"
> > so called "major arcana" cards, 22 of them, for total of 78 cards. I
> > created enumeration type and listed all 78 cards (with Tarot_Card'Pos
> > of course 0..77 an Tarot_Card_Position in that range, and Deck as
> > array(Tarot_Card_Position) of Card_Properties record with name and
> > meaning fields. Using Ada.Numerics.Discrete_Random it works, but I
> > wonder if better solution is possible)! When I've tried to make 4
> > suits of 14 cards and 22 cards in trump "suit" I however failed to see
> > a solution and how I would iterate over such type, so I wonder if that
> > route is possible. Thanks!
> 
> Why the mess with the type "Tarot_Card_Position"?  You can make arrays
> over enumeration types.
> 
> It sound like your problem space doesn't quite match a single
> enumeration type, though.  Maybe you really need a variant record?
> 
>    type Card (Trump : Boolean) is
>       record
>          case Trump is
>             when True =>
>                Trump_Value : Major_Arcana;
>             when False =>
>                Suit        : Suits;
>                Value       : Values;
>       end record;
> 
> The naming is horrible, and the code is untested, but I hope you get the
> idea.
> 
> Greetings,
> 
> Jacob
> -- 
> "Good enough for physics" -- Ridcully

Thanks for the input, I'll look into your suggestion, but the main problem is each card has its "divinatoy meaning". I've used Tarot_Card_Position because it makes more sense to shuffle deck indexed in integer than in enumeration type and draw then a number of cars from it. But I know I wrote some awful code, as I really have little experience and no formal education.

procedure Shuffle (TDeck : in out Deck) is
      position_gen   : position_random.Generator;
      Temporary_Data : Card_Properties;
      Index_Random   : Tarot_Card_Position;
   begin
      position_random.Reset (Gen => position_gen);
      for Index in Tarot_Card_Position'First .. Tarot_Card_Position'Last loop
         Index_Random         := position_random.Random (Gen => position_gen);
         Temporary_Data       := TDeck (Index);
         TDeck (Index)        := TDeck (Index_Random);
         TDeck (Index_Random) := Temporary_Data;
      end loop;
   end Shuffle;

I make a Deck, Initialize it (with all 78 "divinatory meanings" of cards) call this Shuffle and draw then a number of cards. My code is not ideal, it just happen to work, but I've did only some PHP programming and assembler programming back in 80s on 8-bit home computer.

^ permalink raw reply	[relevance 0%]

* Re: Card game deck but with trumps suit for tarot "divination" Is there a better way than enumerating all cards?
  2018-01-28  7:48  4% Card game deck but with trumps suit for tarot "divination" Is there a better way than enumerating all cards? bozovic.bojan
@ 2018-01-28  8:57  0% ` Jacob Sparre Andersen
  2018-01-28  9:23  0%   ` bozovic.bojan
  0 siblings, 1 reply; 200+ results
From: Jacob Sparre Andersen @ 2018-01-28  8:57 UTC (permalink / raw)


bozovic.bojan@gmail.com writes:

> These cards contain of 4 suits of 14 cards each, and special "trump"
> so called "major arcana" cards, 22 of them, for total of 78 cards. I
> created enumeration type and listed all 78 cards (with Tarot_Card'Pos
> of course 0..77 an Tarot_Card_Position in that range, and Deck as
> array(Tarot_Card_Position) of Card_Properties record with name and
> meaning fields. Using Ada.Numerics.Discrete_Random it works, but I
> wonder if better solution is possible)! When I've tried to make 4
> suits of 14 cards and 22 cards in trump "suit" I however failed to see
> a solution and how I would iterate over such type, so I wonder if that
> route is possible. Thanks!

Why the mess with the type "Tarot_Card_Position"?  You can make arrays
over enumeration types.

It sound like your problem space doesn't quite match a single
enumeration type, though.  Maybe you really need a variant record?

   type Card (Trump : Boolean) is
      record
         case Trump is
            when True =>
               Trump_Value : Major_Arcana;
            when False =>
               Suit        : Suits;
               Value       : Values;
      end record;

The naming is horrible, and the code is untested, but I hope you get the
idea.

Greetings,

Jacob
-- 
"Good enough for physics" -- Ridcully


^ permalink raw reply	[relevance 0%]

* Card game deck but with trumps suit for tarot "divination" Is there a better way than enumerating all cards?
@ 2018-01-28  7:48  4% bozovic.bojan
  2018-01-28  8:57  0% ` Jacob Sparre Andersen
  0 siblings, 1 reply; 200+ results
From: bozovic.bojan @ 2018-01-28  7:48 UTC (permalink / raw)


These cards contain of 4 suits of 14 cards each, and special "trump" so called "major arcana" cards, 22 of them, for total of 78 cards. I created enumeration type and listed all 78 cards (with Tarot_Card'Pos of course 0..77 an Tarot_Card_Position in that range, and Deck as array(Tarot_Card_Position) of Card_Properties record with name and meaning fields. Using Ada.Numerics.Discrete_Random it works, but I wonder if better solution is possible)! When I've tried to make 4 suits of 14 cards and 22 cards in trump "suit" I however failed to see a solution and how I would iterate over such type, so I wonder if that route is possible. Thanks!


^ permalink raw reply	[relevance 4%]

* Re: How to access an array using two different indexing schemes
  @ 2017-11-30 23:13  5%                 ` Jerry
  0 siblings, 0 replies; 200+ results
From: Jerry @ 2017-11-30 23:13 UTC (permalink / raw)


On Thursday, November 30, 2017 at 2:50:31 PM UTC-7, Randy Brukardt wrote:
> 
> The only thing that does work is the type conversion in parameter passing 
> (as I originally illustrated). So something like the following should work 
> (should because I didn't try it):
> 
The type conversion at the subroutine level also works for an open array in the formal argument. The following uses an array which is accessed by an access variable--the "usual" declaration method also works, i.e,. if x is declared as 

x : Real_Vector(-4 .. 3);


with Ada.Text_IO; use Ada.Text_IO;
with Ada.Numerics.Long_Real_Arrays; use Ada.Numerics.Long_Real_Arrays;

procedure Randy_V3 is
    type Real_Vector_Access is access Real_Vector;
    x_Ptr : Real_Vector_Access := new Real_Vector(-4 .. 3);
        x : Real_Vector renames x_Ptr.all;
    subtype RV0_7 is Real_Vector(0..7);

    procedure Do_X(x : in out Real_Vector) is
    begin
        for i in x'range loop
            x(i) := x(i) + 0.1;
            Put_Line(i'img & "  " & x(i)'img);
        end loop;
    end Do_X;

    procedure Do_Y(y : in out RV0_7) is
    begin
        for i in y'range loop
            y(i) := y(i) + 0.2;
            Put_Line(i'img & "  " & y(i)'img);
        end loop;
    end Do_Y;

    procedure Do_Y_Open(y : in out Real_Vector) is
    begin
        for i in y'range loop
            y(i) := y(i) + 0.3;
            Put_Line(i'img & "  " & y(i)'img);
        end loop;
    end Do_Y_Open;

begin
    x := (-4.0, -3.0, -2.0, -1.0, 0.0, 1.0, 2.0, 3.0);
    Do_X(x);
    New_Line;
    Do_Y(RV0_7(x));
    New_Line;
    Do_Y_Open(RV0_7(x));
end Randy_V3;


-4  -3.90000000000000E+00
-3  -2.90000000000000E+00
-2  -1.90000000000000E+00
-1  -9.00000000000000E-01
 0   1.00000000000000E-01
 1   1.10000000000000E+00
 2   2.10000000000000E+00
 3   3.10000000000000E+00

 0  -3.70000000000000E+00
 1  -2.70000000000000E+00
 2  -1.70000000000000E+00
 3  -7.00000000000000E-01
 4   3.00000000000000E-01
 5   1.30000000000000E+00
 6   2.30000000000000E+00
 7   3.30000000000000E+00

 0  -3.40000000000000E+00
 1  -2.40000000000000E+00
 2  -1.40000000000000E+00
 3  -4.00000000000000E-01
 4   6.00000000000000E-01
 5   1.60000000000000E+00
 6   2.60000000000000E+00
 7   3.60000000000000E+00

Jerry

^ permalink raw reply	[relevance 5%]

* Re: How to access an array using two different indexing schemes
  2017-11-26  8:58  6%           ` Dmitry A. Kazakov
  2017-11-26 10:31  0%             ` Jerry
@ 2017-11-28  1:31  6%             ` Randy Brukardt
  1 sibling, 0 replies; 200+ results
From: Randy Brukardt @ 2017-11-28  1:31 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
news:ovdvnm$3dt$1@gioia.aioe.org...
> On 2017-11-26 02:07, Jerry wrote:
>> On Friday, November 24, 2017 at 4:38:10 PM UTC-7, Jerry wrote:
>>> I frequently allocate memory for arrays from the heap, as discussed 
>>> previously on this list, like this:
>>>
>>> with Ada.Numerics.Long_Real_Arrays; use Ada.Numerics.Long_Real_Arrays;
>>> procedure Double_Array_2 is
>>>      type Real_Vector_Access is access Real_Vector;
>>>      x_Ptr : Real_Vector_Access := new Real_Vector(-4 .. 3);
>>>          x : Real_Vector renames x_Ptr.all;
>>>      y_Ptr : Real_Vector_Access := new Real_Vector(0 .. 7);
>>>          y : Real_Vector renames y_Ptr.all;
>>> begin
>>>      null;
>>> end Double_Array_2;
>>>
>>> How would I use the 'Address trick in this situation?

Don't. Just type convert X as needed:

with Ada.Numerics.Long_Real_Arrays; use Ada.Numerics.Long_Real_Arrays;
procedure Double_Array_2 is
      type Real_Vector_Access is access Real_Vector;
      x_Ptr : Real_Vector_Access := new Real_Vector(-4 .. 3);
             x : Real_Vector renames x_Ptr.all;
--   y_Ptr : Real_Vector_Access := new Real_Vector(0 .. 7);
-->> This is allocating a new object for Real_Vector, which I don't think 
you want to do.
      subtype RV0_7 is Real_Vector(0..7);
      procedure Do_Y (Y : in out RV0_7) is
      begin
           -- Operations on Y.
      end Do_Y;

     begin
          Do_Y (RV0_7(X));
     end Double_Array_2;

If you used the Address clause hack here, you'd be subject to termination. 
GIGO.

                                  Randy.



^ permalink raw reply	[relevance 6%]

* Re: How to access an array using two different indexing schemes
  2017-11-24 17:37  6% ` A. Cervetti
  2017-11-24 21:48  0%   ` Jerry
@ 2017-11-28  1:25  0%   ` Randy Brukardt
    1 sibling, 1 reply; 200+ results
From: Randy Brukardt @ 2017-11-28  1:25 UTC (permalink / raw)


"A. Cervetti" <andrea.cervetti@gmail.com> wrote in message 
news:e3a1f97e-7cbd-4327-aef6-c18ca9e74bc2@googlegroups.com...
>use attribute 'Address:
>
>with Ada.Text_IO; use Ada.Text_IO;
>with Ada.Float_Text_IO; use Ada.Float_Text_IO;
>with Ada.Numerics.Generic_Real_Arrays;
>
>procedure Double_Array is
>   package Real_Array is new Ada.Numerics.Generic_Real_Arrays(Float);
>   use Real_Array;
>
>   x : Real_Vector(0 .. 4) := (1.0, 2.0, 3.0, 4.0, 5.0);
>   y : Real_Vector(1 .. 5);
>   for Y'Address use X'Address; -- <<<<<<<<<<<<<<<<<<<<

An evil and not guaranteed to work on all implementation technique.

The OP just needs to use an appropriate type conversion to change the bounds 
of their array (odd no one has mentioned that):

If one has:

   subtype RV1_5 is Real_Vector(1..5);

Then the type conversion:
    RV1_5(X) has the new bounds, and (by itself) doesn't copy any memory.

Thus, using a subprogram to temporarily bind the object shouldn't result in 
any copying of the data (no guarantees, of course, but it will always work - 
rememberm avoid premature optimization!):

    procedure Do_Y (Y : RV1_5) is
    begin
         -- Operations on Y.
    end Do_Y;

    ...
    Do_Y (RV1_5(X));

This is the best way to change the bounds of an array (or part of an array) 
in Ada.

                                                            Randy.



begin
   X(0) := 20.0;
   Put(X(0), 0, 0, 0); New_Line;
   Put(Y(1), 0, 0, 0); New_Line;
end Double_Array;

A. 


^ permalink raw reply	[relevance 0%]

* Re: Instantiations of a generic with often encountered arguments
    2017-11-27  8:00  7%     ` Simon Wright
@ 2017-11-27 16:05  3%     ` Shark8
  1 sibling, 0 replies; 200+ results
From: Shark8 @ 2017-11-27 16:05 UTC (permalink / raw)


On Sunday, November 26, 2017 at 7:02:23 PM UTC-7, Victor Porton wrote:
> 
> I am now in analysis-paralysis of whether to define instantiations for often 
> encountered types in advance (globally) or immediately before use.

Ok, I completely understand that problem -- the right way will undoubtedly influence your codebase and you don't want to have to rewrite everything.

Unfortunately I can't give you a hard rule on how you should proceed because, like so many other things, it depends on what you're doing. (e.g. do you want to make SOME_TYPE limited & private, just private, just limited, or neither? It really depends, if you're passing around a handle where there's some sort of reference-counting going on, you'll want limited private to ensure that you're not accidentally mucking about on the internal count. OTOH, if you're implementing a parallel solver, you probably want your data non-limited so you can copy it and feed these copies to your worker-tasks freely.)

For generics, I've found that making a "global instantiation" generic is best when you're either (a) working on an entire [sub-]system that is generic [e.g. a parser that you're going to use multiple times with different syntax-sets] or (b) when the functions themselves are anticipated to be used widely in your code [e.g. the Ada.Numerics.Elementary_Functions example].

One last option is leveraging Ada's visibility/scoping rules to "mix and match" your options; example you have a generic package GENERIC_AUDIO_OPERATIONS containing subprograms that are going to be used all over the audio portion of an application:

With
Application.Generics.GENERIC_AUDIO_OPERATIONS;

Package Application.Subsystems.Audio is

Private
  Package Operations is New GENERIC_AUDIO_OPERATIONS( [[parameters]] );
  Use Operations;
  -- The instantiation is now directly visible/usable to the private and
  -- (IIRC) implementation portions of child packages.
End Application.Subsystems.Audio;

^ permalink raw reply	[relevance 3%]

* Re: Instantiations of a generic with often encountered arguments
  @ 2017-11-27  8:00  7%     ` Simon Wright
  2017-11-27 16:05  3%     ` Shark8
  1 sibling, 0 replies; 200+ results
From: Simon Wright @ 2017-11-27  8:00 UTC (permalink / raw)


Victor Porton <porton@narod.ru> writes:
> Dmitry A. Kazakov wrote:
>
>> On 2017-11-26 01:04, Victor Porton wrote:
>>> Is it a good practice to declare "centralized" (that is in the same
>>> package as a generic packages is defined in, or in a child unit)
>>> instantiations of a generic package with common (that is often
>>> encountered, such as Integer, String, etc.) generic parameters?
>> 
>> Yes, Ada library does so for standard types.
>
> Where?!

e.g.

   with Ada.Numerics.Generic_Elementary_Functions;

   package Ada.Numerics.Elementary_Functions is
     new Ada.Numerics.Generic_Elementary_Functions (Float);

   pragma Pure (Elementary_Functions);

^ permalink raw reply	[relevance 7%]

* Re: How to access an array using two different indexing schemes
  2017-11-26  8:58  6%           ` Dmitry A. Kazakov
@ 2017-11-26 10:31  0%             ` Jerry
  2017-11-28  1:31  6%             ` Randy Brukardt
  1 sibling, 0 replies; 200+ results
From: Jerry @ 2017-11-26 10:31 UTC (permalink / raw)


On Sunday, November 26, 2017 at 1:58:32 AM UTC-7, Dmitry A. Kazakov wrote:
> On 2017-11-26 02:07, Jerry wrote:
> > On Friday, November 24, 2017 at 4:38:10 PM UTC-7, Jerry wrote:
> >> I frequently allocate memory for arrays from the heap, as discussed previously on this list, like this:
> >>
> >> with Ada.Numerics.Long_Real_Arrays; use Ada.Numerics.Long_Real_Arrays;
> >> procedure Double_Array_2 is
> >>      type Real_Vector_Access is access Real_Vector;
> >>      x_Ptr : Real_Vector_Access := new Real_Vector(-4 .. 3);
> >>          x : Real_Vector renames x_Ptr.all;
> >>      y_Ptr : Real_Vector_Access := new Real_Vector(0 .. 7);
> >>          y : Real_Vector renames y_Ptr.all;
> >> begin
> >>      null;
> >> end Double_Array_2;
> >>
> >> How would I use the 'Address trick in this situation?
> >>
> > Any help here? I've spend several hours on this one. I'm not out of
> > ideas but I'm pretty challenged by this. Currently trying things with
> > System.Address_To_Access_Conversions.
> 
> Where is a problem?
> 
> with Ada.Numerics.Long_Real_Arrays; use Ada.Numerics.Long_Real_Arrays;
> procedure Double_Array_2 is
>     type Real_Vector_Access is access Real_Vector;
>     x_Ptr : Real_Vector_Access := new Real_Vector(-4 .. 3);
>     x : Real_Vector renames x_Ptr.all;
>     y : Real_Vector(0..7);
>     for y'Address use x'Address;
> begin
>     null;
> end Double_Array_2;
> 
> -- 
> Regards,
> Dmitry A. Kazakov
> http://www.dmitry-kazakov.de

Thanks, Dmitry. I kept trying to use a pointer for y. I anticipated that I would feel like an idiot when someone showed me how to do this and I was right.

Jerry


^ permalink raw reply	[relevance 0%]

* Re: How to access an array using two different indexing schemes
  2017-11-26  1:07  0%         ` Jerry
@ 2017-11-26  8:58  6%           ` Dmitry A. Kazakov
  2017-11-26 10:31  0%             ` Jerry
  2017-11-28  1:31  6%             ` Randy Brukardt
  0 siblings, 2 replies; 200+ results
From: Dmitry A. Kazakov @ 2017-11-26  8:58 UTC (permalink / raw)


On 2017-11-26 02:07, Jerry wrote:
> On Friday, November 24, 2017 at 4:38:10 PM UTC-7, Jerry wrote:
>> I frequently allocate memory for arrays from the heap, as discussed previously on this list, like this:
>>
>> with Ada.Numerics.Long_Real_Arrays; use Ada.Numerics.Long_Real_Arrays;
>> procedure Double_Array_2 is
>>      type Real_Vector_Access is access Real_Vector;
>>      x_Ptr : Real_Vector_Access := new Real_Vector(-4 .. 3);
>>          x : Real_Vector renames x_Ptr.all;
>>      y_Ptr : Real_Vector_Access := new Real_Vector(0 .. 7);
>>          y : Real_Vector renames y_Ptr.all;
>> begin
>>      null;
>> end Double_Array_2;
>>
>> How would I use the 'Address trick in this situation?
>>
> Any help here? I've spend several hours on this one. I'm not out of
> ideas but I'm pretty challenged by this. Currently trying things with
> System.Address_To_Access_Conversions.

Where is a problem?

with Ada.Numerics.Long_Real_Arrays; use Ada.Numerics.Long_Real_Arrays;
procedure Double_Array_2 is
    type Real_Vector_Access is access Real_Vector;
    x_Ptr : Real_Vector_Access := new Real_Vector(-4 .. 3);
    x : Real_Vector renames x_Ptr.all;
    y : Real_Vector(0..7);
    for y'Address use x'Address;
begin
    null;
end Double_Array_2;

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[relevance 6%]

* Re: How to access an array using two different indexing schemes
  2017-11-24 23:38  7%       ` Jerry
@ 2017-11-26  1:07  0%         ` Jerry
  2017-11-26  8:58  6%           ` Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: Jerry @ 2017-11-26  1:07 UTC (permalink / raw)


On Friday, November 24, 2017 at 4:38:10 PM UTC-7, Jerry wrote:
> I frequently allocate memory for arrays from the heap, as discussed previously on this list, like this:
> 
> with Ada.Numerics.Long_Real_Arrays; use Ada.Numerics.Long_Real_Arrays;
> procedure Double_Array_2 is
>     type Real_Vector_Access is access Real_Vector;
>     x_Ptr : Real_Vector_Access := new Real_Vector(-4 .. 3);
>         x : Real_Vector renames x_Ptr.all;
>     y_Ptr : Real_Vector_Access := new Real_Vector(0 .. 7);
>         y : Real_Vector renames y_Ptr.all;
> begin
>     null;
> end Double_Array_2;
> 
> How would I use the 'Address trick in this situation?
> 
Any help here? I've spend several hours on this one. I'm not out of ideas but I'm pretty challenged by this. Currently trying things with System.Address_To_Access_Conversions.

Jerry

^ permalink raw reply	[relevance 0%]

* Re: How to access an array using two different indexing schemes
  @ 2017-11-24 23:38  7%       ` Jerry
  2017-11-26  1:07  0%         ` Jerry
  0 siblings, 1 reply; 200+ results
From: Jerry @ 2017-11-24 23:38 UTC (permalink / raw)


On Friday, November 24, 2017 at 3:15:35 PM UTC-7, Robert A Duff wrote:
> Jerry writes:
> 
> > On Friday, November 24, 2017 at 10:37:30 AM UTC-7, A. Cervetti wrote:
> >>    for Y'Address use X'Address; -- <<<<<<<<<<<<<<<<<<<<
> 
> > Nice. Thank you. That solves the "version control" or "bookkeeping"
> > problem, but it still requires allocating double memory, for y.
> 
> No, X and Y are allocated at the same address.
> That's the point of this low-level hack.
> 
> - Bob

Oh. That seems to solve all my problems. I did it this way:

with Ada.Numerics.Long_Real_Arrays; use Ada.Numerics.Long_Real_Arrays;
procedure Double_Array_1 is
    x : Real_Vector(-4 .. 3);
    y : Real_Vector(0 .. 7);
    for y'Address use x'Address; -- <<<< 'Address trick
begin
    null;
end Double;

Now I wonder if I could get greedy.

I frequently allocate memory for arrays from the heap, as discussed previously on this list, like this:

with Ada.Numerics.Long_Real_Arrays; use Ada.Numerics.Long_Real_Arrays;
procedure Double_Array_2 is
    type Real_Vector_Access is access Real_Vector;
    x_Ptr : Real_Vector_Access := new Real_Vector(-4 .. 3);
        x : Real_Vector renames x_Ptr.all;
    y_Ptr : Real_Vector_Access := new Real_Vector(0 .. 7);
        y : Real_Vector renames y_Ptr.all;
begin
    null;
end Double_Array_2;

How would I use the 'Address trick in this situation?

Jerry

^ permalink raw reply	[relevance 7%]

* Re: How to access an array using two different indexing schemes
  2017-11-24 17:37  6% ` A. Cervetti
@ 2017-11-24 21:48  0%   ` Jerry
    2017-11-28  1:25  0%   ` Randy Brukardt
  1 sibling, 1 reply; 200+ results
From: Jerry @ 2017-11-24 21:48 UTC (permalink / raw)


On Friday, November 24, 2017 at 10:37:30 AM UTC-7, A. Cervetti wrote:
> use attribute 'Address:
> 
> with Ada.Text_IO; use Ada.Text_IO;
> with Ada.Float_Text_IO; use Ada.Float_Text_IO;
> with Ada.Numerics.Generic_Real_Arrays;
> 
> procedure Double_Array is
>    package Real_Array is new Ada.Numerics.Generic_Real_Arrays(Float);
>    use Real_Array;
>    
>    x : Real_Vector(0 .. 4) := (1.0, 2.0, 3.0, 4.0, 5.0);
>    y : Real_Vector(1 .. 5);
>    for Y'Address use X'Address; -- <<<<<<<<<<<<<<<<<<<<
>    
> begin
>    X(0) := 20.0;
>    Put(X(0), 0, 0, 0); New_Line;
>    Put(Y(1), 0, 0, 0); New_Line;
> end Double_Array;

Nice. Thank you. That solves the "version control" or "bookkeeping" problem, but it still requires allocating double memory, for y.

I had hoped to use an access variable for the role of y so that only a tiny amount of additional memory would be required, and somehow do a type conversion of the y-pointer as it points at x, but I haven't been able yet to figure out how to do the pointer type conversion. Is this even possible?

Jerry


^ permalink raw reply	[relevance 0%]

* Re: How to access an array using two different indexing schemes
  @ 2017-11-24 17:37  6% ` A. Cervetti
  2017-11-24 21:48  0%   ` Jerry
  2017-11-28  1:25  0%   ` Randy Brukardt
  0 siblings, 2 replies; 200+ results
From: A. Cervetti @ 2017-11-24 17:37 UTC (permalink / raw)


Il giorno venerdì 24 novembre 2017 12:42:08 UTC+1, Jerry ha scritto:

> I'm currently looking at System.Address_To_Access_Conversions but I thought I would query the list in the meantime.

use attribute 'Address:

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Float_Text_IO; use Ada.Float_Text_IO;
with Ada.Numerics.Generic_Real_Arrays;

procedure Double_Array is
   package Real_Array is new Ada.Numerics.Generic_Real_Arrays(Float);
   use Real_Array;
   
   x : Real_Vector(0 .. 4) := (1.0, 2.0, 3.0, 4.0, 5.0);
   y : Real_Vector(1 .. 5);
   for Y'Address use X'Address; -- <<<<<<<<<<<<<<<<<<<<
   
begin
   X(0) := 20.0;
   Put(X(0), 0, 0, 0); New_Line;
   Put(Y(1), 0, 0, 0); New_Line;
end Double_Array;

A.

^ permalink raw reply	[relevance 6%]

* Read-write mutex sometimes fails on deadlock
@ 2017-10-28 20:02  1% pascal.malaise
  0 siblings, 0 replies; 200+ results
From: pascal.malaise @ 2017-10-28 20:02 UTC (permalink / raw)


Hi,

[long post because it includes the full sources and output, sorry]

I have a package that implements several kinds of mutexes, including a
read-write mutex. Here is the full source (spec and body) with only the
read-write part.

mutexes.ads
-----------

private with Ada.Task_Identification;
-- Mutex (single and Read_Write) management
package Mutexes is

  -- Kind of mutex
  -- Read_Write allows several readers but one writer at a time.
  --  This implementation is fair but somewhat CPU-consuming because
  --  the arrival of a reader while writer(s) are waiting triggers a
  --  re-evaluation to let it pass if it has a higher (task) priority.
  -- Kind of requested access for a Read_Write mutex
  type Access_Kind is (Read, Write);

  -- Mutex object, free at creation
  type Mutex is tagged limited private;

  -- Get access to a mutex.
  -- With RW mutex (Read_Write), simultaneous read are possible,
  --  but there is only one writer at a time and no reader at that time.
  -- If delay is negative, wait until mutex is got,
  -- If delay is null, try and give up if not free,
  -- If delay is positive, try during the specified delay.
  -- Raises Already_Got if the current task if it has already got the RW mutex
  --  for write.
  -- Note that there is no check of "Read then Write" deadlock.
  Already_Got : exception;
  function Get (A_Mutex      : in out Mutex;
                Waiting_Time : in Duration;
                Kind         : in Access_Kind := Read) return Boolean;
  -- Get access to a mutex : infinite wait.
  procedure Get (A_Mutex      : in out Mutex;
                 Kind         : in Access_Kind := Read);
  function Get (A_Mutex : in out Mutex) return Boolean;


  -- Release access to a mutex.
  -- Raises Not_Owner if current task doesn't own the the RW mutex for write
  --  (no check when releasing RW mutex aquired for read).
  Not_Owner : exception;
  procedure Release (A_Mutex : in out Mutex);

  -- Is current task the "owner" (access got) of a simple mutex
  -- Is it the writer in case of a RW mutex
  function Is_Owner (A_Mutex : in Mutex) return Boolean;

private

  -- Read/write mutex
  -- We want to queue all requests (read and write) within the same queue
  --  to ensure fairness (avoid starvation).
  -- But the condition for read is "no writer" (not Writer)
  --  and for write it is "no writer and no reader"
  --  (not Writer and then Readers = 0)
  -- So the guard of the common queue is "no writer", but a writer may pass it
  --  while there are reader. In this case, we would like to requeue it in the
  --  same queue and in the beginning of it; note that "requeue" requeues at
  --  the end :-(. The artifact is to requeue the task, and all other
  --  tasks queueing after it as well, in an alternate queue (Swapping).
  -- Benefit: a new reader may enter while writer(s) are queueing, if its
  --  priority is better. Fairness ++.
  -- Drawback: each new reader while writer(s) are queueing triggers an open
  --  then a swap of the queues. Perfo --.

  -- So there are two queues
  type Queue_Range is mod 2;

  -- The read/write access lock and queues. No time.
  protected type Rw_Mutex_Protect is

    -- Gets the lock. Blocking.
    entry Mutex_Get (Kind : in Access_Kind);

    -- Releases the lock
    procedure Mutex_Release;

    -- Is current task write owner of the lock
    function Mutex_Owns return Boolean;
  private
    -- Number of readers
    Readers : Natural := 0;
    -- Writer identification
    Owner : Ada.Task_Identification.Task_Id;
    -- Numer of times it has got the write lock
    Writer : Natural := 0;

    -- Two queues, one is active at a time
    entry Queues (Queue_Range) (Kind : in Access_Kind);
    Current_Queue : Queue_Range := Queue_Range'First;
    -- The status of the queue:
    -- Swapping or not
    Swapping : Boolean := False;
    -- If not swapping, is the mutex open or not
    -- if swapping, will it be open or not
    Open : Boolean := True;

  end Rw_Mutex_Protect;

  -- The general purpose mutex
  type Mutex is tagged limited record
    Rw_Mutex : Rw_Mutex_Protect;
  end record;
end Mutexes;


mutexes.adb
-----------

with Ada.Text_Io;
package body Mutexes is

  use type Ada.Task_Identification.Task_Id;
  function Image (Id : in Ada.Task_Identification.Task_Id) return String
           renames Ada.Task_Identification.Image;

  Debug_Set : Boolean := False;
  Debug_On : Boolean := False;
  procedure Trace (Id : in Ada.Task_Identification.Task_Id;
                   Msg : in String) is
  begin
    if not Debug_Set then
      -- Initial setup
      Debug_Set := True;
      Debug_On := True;
    end if;
    if Debug_On then
      Ada.Text_Io.Put_Line (Msg & " " & Image (Id));
    end if;
  end Trace;

  -- The protected object which implements the read/write mutex
  protected body Rw_Mutex_Protect is

    -- Gets the lock. Blocking.
    -- Do not let a new request be inserted in the middle of a queue while
    -- we are swapping queues.
    entry Mutex_Get (Kind : in Access_Kind) when not Swapping is
    begin
      -- Are we already the writer
      if Writer /= 0 and then Mutex_Get'Caller = Owner then
        raise Already_Got;
      end if;

      -- Queue the request in the active queue
      Trace (Mutex_Get'Caller, "Read_Write get queueing");
      requeue Queues(Current_Queue) with abort;
    end Mutex_Get;

    -- Releases the lock. No Check of kind but the lock must have been
    -- got.
    procedure Mutex_Release is
    begin
      if Readers > 0 then
        -- There are readers, one of them is releasing the lock
        Readers := Readers - 1;
        if Readers = 0 then
          -- The last reader leaves, so the lock becomes available
          --  for writers
          Trace (Ada.Task_Identification.Current_Task, "Last reader releases");
          Open := True;
        else
          Trace (Ada.Task_Identification.Current_Task, "Reader releases");
        end if;
      elsif Writer /= 0
      and then Ada.Task_Identification.Current_Task = Owner then
        -- The writer is releasing the lock
        if Writer /= 1 then
          Writer := Writer - 1;
          return;
        end if;
        -- Really releasing
        Trace (Ada.Task_Identification.Current_Task, "Writer releases");
        Writer := 0;
        Open := True;
      else
        -- Called while no lock was got or not called by the writer
        raise Not_Owner;
      end if;
    end Mutex_Release;

    function Mutex_Owns return Boolean is
      (Writer /= 0 and then Ada.Task_Identification.Current_Task = Owner);

    -- Two queues, one active at a time
    -- Passes when swapping queues or else when open
    entry Queues (for Queue in Queue_Range) (Kind : in Access_Kind)
          when Queue = Current_Queue
          and then (Swapping or else Open) is
    begin
      if Swapping then
        -- Swapping queueing tasks from one queue to the other
        Trace (Queues'Caller, "Swapping");
        if Queues(Queue)'Count = 0 then
          -- This is the last task: end of swapping
          -- Open remains unchanged (maybe open by a release)
          Swapping := False;
          Current_Queue := Current_Queue + 1;
          Trace (Queues'Caller, "End swapping");
        end if;
        -- Requeue the task on the other queue
        requeue Queues(Queue + 1) with abort;
      else
        -- The queue is open: The lock is either free or allocated to reader(s)
        if Kind = Read then
          Trace (Queues'Caller, "Another reader");
          -- Read lock
          Readers := Readers + 1;
        else
          -- Write lock:
          -- If we are here, it means that the gate is open so no writer
          --  has already got the lock
          -- Either we get the lock (queue is closed until we release)
          -- or we queue (no currently queueing read can pass)
          -- so in both case, the queue is closed
          -- Note that a new request may re-open the queue and enter
          --  before us if it as a better prio
          Open := False;
          if Readers = 0 then
            -- No reader => we get the write lock
            Writer := 1;
            Owner := Queues'Caller;
            Trace (Queues'Caller, "Writer has got lock");
          else
            -- We have to wait until last reader releases the lock
            -- If we are alone, requeue ourself. Otherwise
            --  requeue in the alternate queue this task, then all the other
            --  queueing tasks, so we remain first (if same prios)
            Swapping := Queues(Queue)'Count > 0;
            if Swapping then
              Trace (Queues'Caller, "Start swapping");
              requeue Queues(Queue + 1) with abort;
            else
              Trace (Queues'Caller, "Writer waits for current reader");
              requeue Queues(Queue) with abort;
            end if;
          end if;
        end if;
      end if;
    end Queues;

  end Rw_Mutex_Protect;

  function Get (A_Mutex      : in out Mutex;
                Waiting_Time : in Duration;
                Kind         : in Access_Kind := Read) return Boolean is
    Result : Boolean;
  begin
    if Waiting_Time < 0.0 then
      -- Negative delay : unconditional waiting
      A_Mutex.Rw_Mutex.Mutex_Get (Kind);
      Result := True;
    else
      select
        A_Mutex.Rw_Mutex.Mutex_Get (Kind);
        Result := True;
      or
        delay Waiting_Time;
        Result := False;
      end select;
    end if;
    return Result;
  end Get;

  function Get (A_Mutex : in out Mutex) return Boolean is
    (Get (A_Mutex, -1.0, Read));

  -- Get a mutex : infinite wait
  procedure Get (A_Mutex      : in out Mutex;
                 Kind         : in Access_Kind := Read) is
    Dummy : Boolean;
  begin
    Dummy := Get (A_Mutex, -1.0, Kind);
  end Get;

  -- Release a mutex
  procedure Release (A_Mutex : in out Mutex) is
  begin
    -- Request releasing
    A_Mutex.Rw_Mutex.Mutex_Release;
  end Release;

  -- Does current task own the mutex (for write)
  function Is_Owner (A_Mutex : Mutex) return Boolean is
  begin
    return A_Mutex.Rw_Mutex.Mutex_Owns;
  end Is_Owner;

end Mutexes;



Finally, I have a test program of the read-write mutex, which creates 10 tasks,
each of them taking the mutex, for read or write, during some time. The tasks
randomly terminate, and when all of them are done then the test is OK.


t_read_write.adb
----------------
with Ada.Text_Io, Ada.Command_Line, Ada.Calendar, Ada.Task_Identification,
     Ada.Numerics.Float_Random;
with Gnat.Calendar;
with Mutexes;
-- Test Read-Write mutex
procedure T_Read_Write is
  pragma Priority(10);

  -- True if gnat, otherwise remove usage of Gnat.Calendar
  Has_Gnat : constant Boolean := True;

  -- The number of tasks
  subtype Range_Actor is Natural range 0 .. 10;
  Main_Index : constant Range_Actor := 0;
  subtype Range_Task is Positive range 1 .. Range_Actor'Last;

  -- Date of last output of a task
  Last_Time : Ada.Calendar.Time;
  use type Ada.Calendar.Time;
  -- Delay of inactivity
  Inactivity : constant Duration := 5.0;

  -- Random generator
  Gen : Ada.Numerics.Float_Random.Generator;
  function Random (Mini : in Integer := 0;
                   Maxi : in Integer := 1) return Integer is
    F : Float;
    Res : Integer;
  begin
    F := Float(Mini) + Ada.Numerics.Float_Random.Random(Gen)
                       * Float(Maxi - Mini);
    Res := Integer (F);
    while Res > Maxi and then Res > Mini loop
      Res := Res - 1;
    end loop;
    return Res;
  end Random;

  -- Image of a date 
  function Image (Date : Ada.Calendar.Time) return String is
    Year   : Ada.Calendar.Year_Number;
    Month  : Ada.Calendar.Month_Number;
    Day    : Ada.Calendar.Day_Number;

    Hour       : Gnat.Calendar.Hour_Number;
    Minute     : Gnat.Calendar.Minute_Number;
    Second     : Gnat.Calendar.Second_Number;
    Sub_Second : Gnat.Calendar.Second_Duration;
    function Img (D : Gnat.Calendar.Second_Duration) return String is
      S : constant String := D'Img;
    begin
      return S(3 .. S'Last);
    end Img;
    Dur    : Ada.Calendar.Day_Duration;
    function Img (N : Integer) return String is
      S : constant String := N'Img;
    begin
      if S'Last = 2 then
        -- " d", 1 digit => "0" & d
        return "0" & S(2);
      else
        -- " dd", d
        return S(2 .. S'Last);
      end if;
    end Img;
    
  begin
    if Has_Gnat then
      Gnat.Calendar.Split (Date, Year, Month, Day, Hour, Minute, Second,
                           Sub_Second);
      return Img (Year) & "-" & Img (Month) & "-" & Img (Day) & "T"
           & Img (Hour) & ":" & Img (Minute) & ":" & Img (Second)
           & Img (Sub_Second);

    else
      Ada.Calendar.Split (Date, Year, Month, Day, Dur);
      return Img (Year) & "/" & Img (Month) & "/" & Img (Day) & Dur'Img;
    end if;
  end Image;

  -- Put a task activity
  procedure Put_Line (Index : in Range_Actor; Msg : in String) is
  begin
    Last_Time := Ada.Calendar.Clock;
    declare
      Date : constant String := Image (Last_Time);
      Str : constant String
          := (if Index in Range_Task then Index'Img else "Main")
           & " " & Msg;
    begin
      Ada.Text_Io.Put_Line (Date & " " & Str);
    end;
  end Put_Line;
  Lock : access Mutexes.Mutex;

  -- The client tasks
  task type T is
   pragma Priority(10);
    entry Num (I : in Range_Task);
    entry Done;
  end T;

  function Image (D : Duration) return String is
    Str : constant String := D'Img;
  begin
    return Str (1 .. 4);
  end Image;

  task body T is
    Index : Range_Task;
    Dur : Duration;
    Kind : Mutexes.Access_Kind;
    subtype Str5 is String (1 .. 5);
    Kind_Strs : constant array (Mutexes.Access_Kind) of Str5 := (
      Mutexes.Read  => " Read",
      Mutexes.Write => "Write");
    Res : Boolean;
  begin
    -- Get name
    accept Num (I : in Range_Task) do
      Index := I;
    end Num;
    Put_Line (Index ,
      "Task started, id "
    & Ada.Task_Identification.Image (Ada.Task_Identification.Current_Task));
    -- Work until termination requested in Critical
    loop
      delay 0.01;
      -- Wait from -0.1 to 0.5
      Dur := Duration (Random (-1, 5)) / 10.0;
      -- 10% chances to write
      if Random (0, 9) = 0 then
        Kind := Mutexes.Write;
      else
        Kind := Mutexes.Read;
      end if;
      -- Get lock
      Put_Line (Index, "get " & Kind_Strs(Kind) & " " & Image(Dur));
      Res := Lock.Get (Dur, Kind);
      -- Trace result
      if Res then
        Put_Line (Index, "OK");
      else
        Put_Line (Index, "NOK");
      end if;

      if Res then
        -- Got it: Work (wait) from 0.1 to 0.5
        Put_Line (Index, "waiting");
        delay Duration (Random (1, 5)) / 10.0;
        Put_Line (Index, "waited");

        -- Release lock
        Put_Line (Index, "release");
        Lock.Release;
      end if;

      -- 10% chances to terminate
      exit when Random (0, 9) = 0;
    end loop;
    Put_Line (Index, "terminate");
    -- Ready to end
    accept Done;
  end T;

  Tasks : array (Range_Task) of T;
  Runs  : array (Range_Task) of Boolean;
  Nb_Run : Natural;

-- The main: activate and monitor the tasks
begin
  Lock := new Mutexes.Mutex;

  -- Randomize
  Ada.Numerics.Float_Random.Reset (Gen, 
    Integer (Ada.Calendar.Seconds (Ada.Calendar.Clock)));

  -- Give to each actor it's name
  Put_Line (Main_Index, "Starting");
  Nb_Run := 0;
  for I in Range_Task loop
    Tasks(I).Num (I);
    Runs(I) := True;
    Nb_Run := Nb_Run + 1;
  end loop;

  -- Wait until termination of all tasks
  Main: while Nb_Run /= 0 loop

    -- Try to terminate tasks: wait 1s altogether
    for I in Range_Task loop
      if Runs(I) then
        select
          Tasks(I).Done;
          Runs(I) := False;
          Nb_Run := Nb_Run - 1;
        or
          delay 1.0 / Duration(Nb_Run);
        end select;
      end if;
    end loop;

    -- Monitor activity
    if Ada.Calendar.Clock - Last_Time > Inactivity then
      -- Deadlock detected => abort tasks
      Put_Line (Main_Index, "Deadlock detected, aborting");
      Ada.Command_Line.Set_Exit_Status (1);
      for I in Range_Task loop
        if Runs(I) then
          abort Tasks(I);
          -- This will exit Main
          Nb_Run := Nb_Run - 1;
        end if;
      end loop;
    end if;
  end loop Main;

  Put_Line (Main_Index, "Done");

end T_Read_Write;


Most of the time it works, but from time to time (every 100 to 1000 iterations)
the test fails: the main detects a deadlock because of no output activity during
more than 5 secs, and exits on error.
You can test on Unix with the following scripts (launch "./Loop"):

trw
---
#!/bin/bash
./t_read_write >out 2>err

Loop
----
#!/bin/bash

# Loop until failure
res=0
let n=0+1
while [ $res -eq 0 ] ; do
  echo `date +"%Y-%m-%dT%H:%M:%S"`" Iteration "$n":"
  ./trw
  if [ $? -ne 0 ] ; then
    echo "Failed!"
    exit 1
  fi
  let n=$n+1
done



When everything is OK all the tasks terminate one after the other, but in case
of failure, here is the output:

2017-10-28T21:15:21.139556000 Main Starting
2017-10-28T21:15:21.139602000  1 Task started, id tasks(1)_0000000000E63F10
2017-10-28T21:15:21.139618000  2 Task started, id tasks(2)_0000000000E68040
2017-10-28T21:15:21.139644000  3 Task started, id tasks(3)_0000000000E6B650
2017-10-28T21:15:21.139662000  4 Task started, id tasks(4)_0000000000E6EC60
2017-10-28T21:15:21.139679000  5 Task started, id tasks(5)_0000000000E72270
2017-10-28T21:15:21.139695000  6 Task started, id tasks(6)_0000000000E75880
2017-10-28T21:15:21.139709000  7 Task started, id tasks(7)_0000000000E78E90
2017-10-28T21:15:21.139732000  8 Task started, id tasks(8)_0000000000E7C4A0
2017-10-28T21:15:21.139752000  9 Task started, id tasks(9)_0000000000E7FAB0
2017-10-28T21:15:21.139759000  10 Task started, id tasks(10)_0000000000E830C0
2017-10-28T21:15:21.149687000  1 get  Read  0.0
2017-10-28T21:15:21.149690000  3 get Write  0.1
2017-10-28T21:15:21.149700000  2 get  Read  0.0
Read_Write get queueing tasks(1)_0000000000E63F10
2017-10-28T21:15:21.149744000  5 get  Read  0.0
Another reader tasks(1)_0000000000E63F10
2017-10-28T21:15:21.149782000  4 get Write  0.5
Read_Write get queueing tasks(3)_0000000000E6B650
Writer waits for current reader tasks(3)_0000000000E6B650
2017-10-28T21:15:21.149804000  8 get  Read  0.1
2017-10-28T21:15:21.149786000  1 OK
2017-10-28T21:15:21.149769000  6 get  Read  0.0
Read_Write get queueing tasks(2)_0000000000E68040
2017-10-28T21:15:21.149825000  9 get  Read  0.5
2017-10-28T21:15:21.149829000  2 NOK
Read_Write get queueing tasks(9)_0000000000E7FAB0
2017-10-28T21:15:21.149855000  10 get  Read  0.0
2017-10-28T21:15:21.149875000  7 get  Read  0.2
2017-10-28T21:15:21.149816000  1 waiting
Read_Write get queueing tasks(4)_0000000000E6EC60
Read_Write get queueing tasks(8)_0000000000E7C4A0
Read_Write get queueing tasks(6)_0000000000E75880
Read_Write get queueing tasks(5)_0000000000E72270
2017-10-28T21:15:21.149917000  6 NOK
2017-10-28T21:15:21.149926000  5 NOK
Read_Write get queueing tasks(10)_0000000000E830C0
Read_Write get queueing tasks(7)_0000000000E78E90
2017-10-28T21:15:21.149940000  10 NOK
2017-10-28T21:15:21.159909000  2 get  Read  0.1
Read_Write get queueing tasks(2)_0000000000E68040
2017-10-28T21:15:21.159990000  5 get  Read  0.3
Read_Write get queueing tasks(5)_0000000000E72270
2017-10-28T21:15:21.160006000  10 get  Read  0.5
2017-10-28T21:15:21.159993000  6 get  Read  0.0
Read_Write get queueing tasks(6)_0000000000E75880
2017-10-28T21:15:21.160032000  6 NOK
Read_Write get queueing tasks(10)_0000000000E830C0
2017-10-28T21:15:21.170103000  6 get  Read  0.4
Read_Write get queueing tasks(6)_0000000000E75880
2017-10-28T21:15:21.249871000  3 NOK
2017-10-28T21:15:21.249967000  8 NOK
2017-10-28T21:15:21.259960000  2 NOK
2017-10-28T21:15:21.259964000  3 get  Read  0.1
Read_Write get queueing tasks(3)_0000000000E6B650
2017-10-28T21:15:21.260036000  8 get  Read -0.1
Read_Write get queueing tasks(8)_0000000000E7C4A0
2017-10-28T21:15:21.270048000  2 get  Read  0.0
Read_Write get queueing tasks(2)_0000000000E68040
2017-10-28T21:15:21.270066000  2 NOK
2017-10-28T21:15:21.280139000  2 get  Read  0.1
Read_Write get queueing tasks(2)_0000000000E68040
2017-10-28T21:15:21.349953000  1 waited
2017-10-28T21:15:21.349976000  1 release
Last reader releases tasks(1)_0000000000E63F10
Another reader tasks(9)_0000000000E7FAB0
Start swapping tasks(4)_0000000000E6EC60
Swapping tasks(7)_0000000000E78E90
2017-10-28T21:15:21.350007000  9 OK
2017-10-28T21:15:21.350051000  9 waiting
Swapping tasks(5)_0000000000E72270
2017-10-28T21:15:21.360060000  1 get  Read  0.0
Swapping tasks(10)_0000000000E830C0
Swapping tasks(6)_0000000000E75880
Swapping tasks(8)_0000000000E7C4A0
Swapping tasks(2)_0000000000E68040
End swapping tasks(2)_0000000000E68040
Read_Write get queueing tasks(1)_0000000000E63F10
2017-10-28T21:15:21.360109000  3 NOK
2017-10-28T21:15:21.360121000  1 NOK
2017-10-28T21:15:21.370195000  3 get  Read  0.3
Read_Write get queueing tasks(3)_0000000000E6B650
2017-10-28T21:15:21.370204000  1 get Write  0.0
Read_Write get queueing tasks(1)_0000000000E63F10
2017-10-28T21:15:21.370242000  1 NOK
2017-10-28T21:15:21.380223000  2 NOK
2017-10-28T21:15:21.380324000  1 get  Read -0.1
Read_Write get queueing tasks(1)_0000000000E63F10
2017-10-28T21:15:21.390298000  2 get  Read  0.2
Read_Write get queueing tasks(2)_0000000000E68040
2017-10-28T21:15:21.460071000  5 NOK
2017-10-28T21:15:21.470153000  5 get  Read  0.0
Read_Write get queueing tasks(5)_0000000000E72270
2017-10-28T21:15:21.470170000  5 NOK
2017-10-28T21:15:21.480242000  5 get  Read  0.1
Read_Write get queueing tasks(5)_0000000000E72270
2017-10-28T21:15:21.570194000  6 NOK
2017-10-28T21:15:21.580275000  6 get  Read  0.0
Read_Write get queueing tasks(6)_0000000000E75880
2017-10-28T21:15:21.580293000  6 NOK
2017-10-28T21:15:21.580321000  5 NOK
2017-10-28T21:15:21.590365000  2 NOK
2017-10-28T21:15:21.590374000  6 get  Read  0.4
Read_Write get queueing tasks(6)_0000000000E75880
2017-10-28T21:15:21.590401000  5 get  Read  0.2
Read_Write get queueing tasks(5)_0000000000E72270
2017-10-28T21:15:21.600438000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
2017-10-28T21:15:21.649962000  4 NOK
2017-10-28T21:15:21.660056000  4 get  Read  0.2
Read_Write get queueing tasks(4)_0000000000E6EC60
2017-10-28T21:15:21.660107000  10 NOK
2017-10-28T21:15:21.670184000  10 get  Read  0.0
Read_Write get queueing tasks(10)_0000000000E830C0
2017-10-28T21:15:21.670203000  10 NOK
2017-10-28T21:15:21.670286000  3 NOK
2017-10-28T21:15:21.680277000  10 get  Read -0.1
Read_Write get queueing tasks(10)_0000000000E830C0
2017-10-28T21:15:21.680365000  3 get  Read  0.3
Read_Write get queueing tasks(3)_0000000000E6B650
2017-10-28T21:15:21.750125000  9 waited
2017-10-28T21:15:21.750140000  9 release
Last reader releases tasks(9)_0000000000E7FAB0
Another reader tasks(8)_0000000000E7C4A0
Another reader tasks(1)_0000000000E63F10
Another reader tasks(6)_0000000000E75880
2017-10-28T21:15:21.750191000  1 OK
2017-10-28T21:15:21.750202000  6 OK
Another reader tasks(5)_0000000000E72270
2017-10-28T21:15:21.750215000  6 waiting
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:21.750166000  8 OK
2017-10-28T21:15:21.750251000  5 OK
Another reader tasks(4)_0000000000E6EC60
2017-10-28T21:15:21.750264000  5 waiting
2017-10-28T21:15:21.750275000  4 OK
2017-10-28T21:15:21.750286000  2 OK
2017-10-28T21:15:21.750298000  2 waiting
Another reader tasks(10)_0000000000E830C0
2017-10-28T21:15:21.750287000  4 waiting
2017-10-28T21:15:21.750254000  8 waiting
Another reader tasks(3)_0000000000E6B650
2017-10-28T21:15:21.750353000  9 terminate
2017-10-28T21:15:21.750356000  3 OK
2017-10-28T21:15:21.750205000  1 waiting
2017-10-28T21:15:21.750381000  3 waiting
2017-10-28T21:15:21.750338000  10 OK
2017-10-28T21:15:21.750420000  10 waiting
2017-10-28T21:15:21.950478000  3 waited
2017-10-28T21:15:21.950503000  3 release
Reader releases tasks(3)_0000000000E6B650
2017-10-28T21:15:21.960583000  3 get  Read  0.0
Read_Write get queueing tasks(3)_0000000000E6B650
Another reader tasks(3)_0000000000E6B650
2017-10-28T21:15:21.960607000  3 OK
2017-10-28T21:15:21.960615000  3 waiting
2017-10-28T21:15:22.150289000  6 waited
2017-10-28T21:15:22.150308000  6 release
Reader releases tasks(6)_0000000000E75880
2017-10-28T21:15:22.150351000  5 waited
2017-10-28T21:15:22.150361000  5 release
Reader releases tasks(5)_0000000000E72270
2017-10-28T21:15:22.150377000  2 waited
2017-10-28T21:15:22.150386000  2 release
Reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:22.150411000  4 waited
2017-10-28T21:15:22.150425000  4 release
Reader releases tasks(4)_0000000000E6EC60
2017-10-28T21:15:22.150444000  8 waited
2017-10-28T21:15:22.150453000  8 release
Reader releases tasks(8)_0000000000E7C4A0
2017-10-28T21:15:22.150488000  10 waited
2017-10-28T21:15:22.150498000  10 release
Reader releases tasks(10)_0000000000E830C0
2017-10-28T21:15:22.160386000  5 get  Read  0.3
2017-10-28T21:15:22.160388000  6 get  Read  0.3
Read_Write get queueing tasks(5)_0000000000E72270
Another reader tasks(5)_0000000000E72270
Read_Write get queueing tasks(6)_0000000000E75880
Another reader tasks(6)_0000000000E75880
2017-10-28T21:15:22.160455000  2 get  Read  0.1
2017-10-28T21:15:22.160498000  4 get  Read  0.2
2017-10-28T21:15:22.160457000  6 OK
2017-10-28T21:15:22.160517000  6 waiting
Read_Write get queueing tasks(2)_0000000000E68040
2017-10-28T21:15:22.160433000  5 OK
2017-10-28T21:15:22.160542000  8 get  Read  0.0
2017-10-28T21:15:22.160547000  5 waiting
Another reader tasks(2)_0000000000E68040
Read_Write get queueing tasks(4)_0000000000E6EC60
Another reader tasks(4)_0000000000E6EC60
2017-10-28T21:15:22.160580000  2 OK
2017-10-28T21:15:22.160611000  4 OK
Read_Write get queueing tasks(8)_0000000000E7C4A0
2017-10-28T21:15:22.160578000  10 get  Read  0.4
2017-10-28T21:15:22.160624000  4 waiting
Another reader tasks(8)_0000000000E7C4A0
Read_Write get queueing tasks(10)_0000000000E830C0
Another reader tasks(10)_0000000000E830C0
2017-10-28T21:15:22.160615000  2 waiting
2017-10-28T21:15:22.160655000  8 OK
2017-10-28T21:15:22.160674000  10 OK
2017-10-28T21:15:22.160692000  8 waiting
2017-10-28T21:15:22.160702000  10 waiting
2017-10-28T21:15:22.250462000  1 waited
2017-10-28T21:15:22.250475000  1 release
Reader releases tasks(1)_0000000000E63F10
2017-10-28T21:15:22.260551000  1 get  Read  0.0
Read_Write get queueing tasks(1)_0000000000E63F10
Another reader tasks(1)_0000000000E63F10
2017-10-28T21:15:22.260571000  1 OK
2017-10-28T21:15:22.260579000  1 waiting
2017-10-28T21:15:22.260775000  10 waited
2017-10-28T21:15:22.260785000  10 release
Reader releases tasks(10)_0000000000E830C0
2017-10-28T21:15:22.270860000  10 get  Read -0.1
Read_Write get queueing tasks(10)_0000000000E830C0
Another reader tasks(10)_0000000000E830C0
2017-10-28T21:15:22.270879000  10 OK
2017-10-28T21:15:22.270887000  10 waiting
2017-10-28T21:15:22.360594000  6 waited
2017-10-28T21:15:22.360619000  6 release
Reader releases tasks(6)_0000000000E75880
2017-10-28T21:15:22.360646000  1 waited
2017-10-28T21:15:22.360658000  1 release
Reader releases tasks(1)_0000000000E63F10
2017-10-28T21:15:22.360684000  4 waited
2017-10-28T21:15:22.360686000  3 waited
2017-10-28T21:15:22.360696000  4 release
Reader releases tasks(4)_0000000000E6EC60
2017-10-28T21:15:22.360706000  3 release
2017-10-28T21:15:22.360723000  4 terminate
Reader releases tasks(3)_0000000000E6B650
2017-10-28T21:15:22.360743000  2 waited
2017-10-28T21:15:22.360767000  2 release
Reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:22.370699000  6 get  Read -0.1
Read_Write get queueing tasks(6)_0000000000E75880
Another reader tasks(6)_0000000000E75880
2017-10-28T21:15:22.370720000  6 OK
2017-10-28T21:15:22.370728000  6 waiting
2017-10-28T21:15:22.370735000  1 get  Read  0.0
Read_Write get queueing tasks(1)_0000000000E63F10
Another reader tasks(1)_0000000000E63F10
2017-10-28T21:15:22.370754000  1 OK
2017-10-28T21:15:22.370762000  1 waiting
2017-10-28T21:15:22.370817000  3 get  Read  0.0
Read_Write get queueing tasks(3)_0000000000E6B650
Another reader tasks(3)_0000000000E6B650
2017-10-28T21:15:22.370835000  3 OK
2017-10-28T21:15:22.370838000  2 get  Read  0.0
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:22.370843000  3 waiting
2017-10-28T21:15:22.370866000  2 OK
2017-10-28T21:15:22.370882000  2 waiting
2017-10-28T21:15:22.460633000  5 waited
2017-10-28T21:15:22.460653000  5 release
Reader releases tasks(5)_0000000000E72270
2017-10-28T21:15:22.460667000  5 terminate
2017-10-28T21:15:22.560780000  8 waited
2017-10-28T21:15:22.560798000  8 release
Reader releases tasks(8)_0000000000E7C4A0
2017-10-28T21:15:22.570880000  8 get  Read  0.3
Read_Write get queueing tasks(8)_0000000000E7C4A0
Another reader tasks(8)_0000000000E7C4A0
2017-10-28T21:15:22.570902000  8 OK
2017-10-28T21:15:22.570911000  8 waiting
2017-10-28T21:15:22.570949000  2 waited
2017-10-28T21:15:22.570959000  2 release
Reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:22.581035000  2 get  Read  0.2
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:22.581054000  2 OK
2017-10-28T21:15:22.581062000  2 waiting
2017-10-28T21:15:22.670800000  6 waited
2017-10-28T21:15:22.670856000  6 release
Reader releases tasks(6)_0000000000E75880
2017-10-28T21:15:22.680902000  6 get  Read  0.2
Read_Write get queueing tasks(6)_0000000000E75880
Another reader tasks(6)_0000000000E75880
2017-10-28T21:15:22.680930000  6 OK
2017-10-28T21:15:22.680938000  6 waiting
2017-10-28T21:15:22.770837000  1 waited
2017-10-28T21:15:22.770857000  1 release
Reader releases tasks(1)_0000000000E63F10
2017-10-28T21:15:22.770938000  3 waited
2017-10-28T21:15:22.770939000  10 waited
2017-10-28T21:15:22.770951000  3 release
Reader releases tasks(3)_0000000000E6B650
2017-10-28T21:15:22.770965000  10 release
Reader releases tasks(10)_0000000000E830C0
2017-10-28T21:15:22.780936000  1 get  Read  0.1
Read_Write get queueing tasks(1)_0000000000E63F10
Another reader tasks(1)_0000000000E63F10
2017-10-28T21:15:22.780975000  1 OK
2017-10-28T21:15:22.780983000  1 waiting
2017-10-28T21:15:22.781041000  3 get  Read  0.2
Read_Write get queueing tasks(3)_0000000000E6B650
Another reader tasks(3)_0000000000E6B650
2017-10-28T21:15:22.781059000  10 get  Read  0.0
Read_Write get queueing tasks(10)_0000000000E830C0
Another reader tasks(10)_0000000000E830C0
2017-10-28T21:15:22.781059000  3 OK
2017-10-28T21:15:22.781092000  10 OK
2017-10-28T21:15:22.781102000  3 waiting
2017-10-28T21:15:22.781112000  10 waiting
2017-10-28T21:15:22.881010000  6 waited
2017-10-28T21:15:22.881023000  6 release
Reader releases tasks(6)_0000000000E75880
2017-10-28T21:15:22.891099000  6 get  Read  0.4
Read_Write get queueing tasks(6)_0000000000E75880
Another reader tasks(6)_0000000000E75880
2017-10-28T21:15:22.891118000  6 OK
2017-10-28T21:15:22.891126000  6 waiting
2017-10-28T21:15:22.981185000  3 waited
2017-10-28T21:15:22.981200000  3 release
Reader releases tasks(3)_0000000000E6B650
2017-10-28T21:15:22.991277000  3 get  Read  0.3
Read_Write get queueing tasks(3)_0000000000E6B650
Another reader tasks(3)_0000000000E6B650
2017-10-28T21:15:22.991297000  3 OK
2017-10-28T21:15:22.991305000  3 waiting
2017-10-28T21:15:23.070985000  8 waited
2017-10-28T21:15:23.071001000  8 release
Reader releases tasks(8)_0000000000E7C4A0
2017-10-28T21:15:23.081054000  1 waited
2017-10-28T21:15:23.081066000  1 release
Reader releases tasks(1)_0000000000E63F10
2017-10-28T21:15:23.081078000  8 get  Read  0.4
Read_Write get queueing tasks(8)_0000000000E7C4A0
Another reader tasks(8)_0000000000E7C4A0
2017-10-28T21:15:23.081098000  8 OK
2017-10-28T21:15:23.081106000  8 waiting
2017-10-28T21:15:23.081130000  2 waited
2017-10-28T21:15:23.081139000  2 release
Reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:23.091142000  1 get  Read  0.0
Read_Write get queueing tasks(1)_0000000000E63F10
Another reader tasks(1)_0000000000E63F10
2017-10-28T21:15:23.091162000  1 OK
2017-10-28T21:15:23.091170000  1 waiting
2017-10-28T21:15:23.091220000  2 get  Read  0.2
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:23.091242000  2 OK
2017-10-28T21:15:23.091250000  2 waiting
2017-10-28T21:15:23.091369000  3 waited
2017-10-28T21:15:23.091379000  3 release
Reader releases tasks(3)_0000000000E6B650
2017-10-28T21:15:23.091391000  3 terminate
2017-10-28T21:15:23.181190000  10 waited
2017-10-28T21:15:23.181206000  10 release
Reader releases tasks(10)_0000000000E830C0
2017-10-28T21:15:23.191284000  10 get  Read  0.4
Read_Write get queueing tasks(10)_0000000000E830C0
Another reader tasks(10)_0000000000E830C0
2017-10-28T21:15:23.191304000  10 OK
2017-10-28T21:15:23.191312000  10 waiting
2017-10-28T21:15:23.291193000  6 waited
2017-10-28T21:15:23.291207000  6 release
Reader releases tasks(6)_0000000000E75880
2017-10-28T21:15:23.291316000  2 waited
2017-10-28T21:15:23.291329000  2 release
Reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:23.301282000  6 get  Read  0.1
Read_Write get queueing tasks(6)_0000000000E75880
Another reader tasks(6)_0000000000E75880
2017-10-28T21:15:23.301302000  6 OK
2017-10-28T21:15:23.301310000  6 waiting
2017-10-28T21:15:23.301406000  2 get  Read  0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:23.301442000  2 OK
2017-10-28T21:15:23.301450000  2 waiting
2017-10-28T21:15:23.381183000  8 waited
2017-10-28T21:15:23.381228000  8 release
Reader releases tasks(8)_0000000000E7C4A0
2017-10-28T21:15:23.391314000  8 get  Read  0.2
Read_Write get queueing tasks(8)_0000000000E7C4A0
Another reader tasks(8)_0000000000E7C4A0
2017-10-28T21:15:23.391339000  8 OK
2017-10-28T21:15:23.391347000  8 waiting
2017-10-28T21:15:23.501526000  2 waited
2017-10-28T21:15:23.501556000  2 release
Reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:23.511639000  2 get  Read  0.3
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:23.511663000  2 OK
2017-10-28T21:15:23.511671000  2 waiting
2017-10-28T21:15:23.591239000  1 waited
2017-10-28T21:15:23.591261000  1 release
Reader releases tasks(1)_0000000000E63F10
2017-10-28T21:15:23.591417000  8 waited
2017-10-28T21:15:23.591432000  8 release
Reader releases tasks(8)_0000000000E7C4A0
2017-10-28T21:15:23.601334000  1 get  Read  0.2
Read_Write get queueing tasks(1)_0000000000E63F10
Another reader tasks(1)_0000000000E63F10
2017-10-28T21:15:23.601356000  1 OK
2017-10-28T21:15:23.601365000  1 waiting
2017-10-28T21:15:23.601513000  8 get  Read  0.5
Read_Write get queueing tasks(8)_0000000000E7C4A0
Another reader tasks(8)_0000000000E7C4A0
2017-10-28T21:15:23.601535000  8 OK
2017-10-28T21:15:23.601544000  8 waiting
2017-10-28T21:15:23.691386000  10 waited
2017-10-28T21:15:23.691426000  10 release
Reader releases tasks(10)_0000000000E830C0
2017-10-28T21:15:23.701508000  10 get  Read -0.1
Read_Write get queueing tasks(10)_0000000000E830C0
Another reader tasks(10)_0000000000E830C0
2017-10-28T21:15:23.701530000  10 OK
2017-10-28T21:15:23.701538000  10 waiting
2017-10-28T21:15:23.801385000  6 waited
2017-10-28T21:15:23.801402000  6 release
Reader releases tasks(6)_0000000000E75880
2017-10-28T21:15:23.811480000  6 get  Read  0.3
Read_Write get queueing tasks(6)_0000000000E75880
Another reader tasks(6)_0000000000E75880
2017-10-28T21:15:23.811501000  6 OK
2017-10-28T21:15:23.811509000  6 waiting
2017-10-28T21:15:23.901439000  1 waited
2017-10-28T21:15:23.901452000  1 release
Reader releases tasks(1)_0000000000E63F10
2017-10-28T21:15:23.901611000  10 waited
2017-10-28T21:15:23.901623000  10 release
Reader releases tasks(10)_0000000000E830C0
2017-10-28T21:15:23.901637000  10 terminate
2017-10-28T21:15:23.911529000  1 get  Read  0.0
Read_Write get queueing tasks(1)_0000000000E63F10
Another reader tasks(1)_0000000000E63F10
2017-10-28T21:15:23.911553000  1 OK
2017-10-28T21:15:23.911561000  1 waiting
2017-10-28T21:15:23.911744000  2 waited
2017-10-28T21:15:23.911758000  2 release
Reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:23.921835000  2 get  Read  0.3
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:23.921856000  2 OK
2017-10-28T21:15:23.921864000  2 waiting
2017-10-28T21:15:24.101621000  8 waited
2017-10-28T21:15:24.101640000  8 release
Reader releases tasks(8)_0000000000E7C4A0
2017-10-28T21:15:24.111575000  6 waited
2017-10-28T21:15:24.111589000  6 release
Reader releases tasks(6)_0000000000E75880
2017-10-28T21:15:24.111717000  8 get  Read  0.3
Read_Write get queueing tasks(8)_0000000000E7C4A0
Another reader tasks(8)_0000000000E7C4A0
2017-10-28T21:15:24.111737000  8 OK
2017-10-28T21:15:24.111745000  8 waiting
2017-10-28T21:15:24.121665000  6 get  Read  0.2
Read_Write get queueing tasks(6)_0000000000E75880
Another reader tasks(6)_0000000000E75880
2017-10-28T21:15:24.121684000  6 OK
2017-10-28T21:15:24.121692000  6 waiting
2017-10-28T21:15:24.211634000  1 waited
2017-10-28T21:15:24.211658000  1 release
Reader releases tasks(1)_0000000000E63F10
2017-10-28T21:15:24.221736000  6 waited
2017-10-28T21:15:24.221737000  1 get  Read  0.0
Read_Write get queueing tasks(1)_0000000000E63F10
Another reader tasks(1)_0000000000E63F10
2017-10-28T21:15:24.221767000  6 release
Reader releases tasks(6)_0000000000E75880
2017-10-28T21:15:24.221793000  1 OK
2017-10-28T21:15:24.221834000  1 waiting
2017-10-28T21:15:24.221931000  2 waited
2017-10-28T21:15:24.221941000  2 release
Reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:24.231875000  6 get  Read  0.1
Read_Write get queueing tasks(6)_0000000000E75880
Another reader tasks(6)_0000000000E75880
2017-10-28T21:15:24.231895000  6 OK
2017-10-28T21:15:24.231903000  6 waiting
2017-10-28T21:15:24.232011000  2 get  Read  0.0
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:24.232030000  2 OK
2017-10-28T21:15:24.232037000  2 waiting
2017-10-28T21:15:24.411815000  8 waited
2017-10-28T21:15:24.411839000  8 release
Reader releases tasks(8)_0000000000E7C4A0
2017-10-28T21:15:24.421919000  8 get  Read -0.1
Read_Write get queueing tasks(8)_0000000000E7C4A0
Another reader tasks(8)_0000000000E7C4A0
2017-10-28T21:15:24.421940000  8 OK
2017-10-28T21:15:24.421948000  8 waiting
2017-10-28T21:15:24.431974000  6 waited
2017-10-28T21:15:24.431986000  6 release
Reader releases tasks(6)_0000000000E75880
2017-10-28T21:15:24.442064000  6 get  Read  0.3
Read_Write get queueing tasks(6)_0000000000E75880
Another reader tasks(6)_0000000000E75880
2017-10-28T21:15:24.442087000  6 OK
2017-10-28T21:15:24.442094000  6 waiting
2017-10-28T21:15:24.521907000  1 waited
2017-10-28T21:15:24.521922000  1 release
Reader releases tasks(1)_0000000000E63F10
2017-10-28T21:15:24.531998000  1 get  Read  0.2
Read_Write get queueing tasks(1)_0000000000E63F10
Another reader tasks(1)_0000000000E63F10
2017-10-28T21:15:24.532018000  1 OK
2017-10-28T21:15:24.532026000  1 waiting
2017-10-28T21:15:24.532108000  2 waited
2017-10-28T21:15:24.532119000  2 release
Reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:24.542201000  2 get  Read  0.3
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:24.542224000  2 OK
2017-10-28T21:15:24.542232000  2 waiting
2017-10-28T21:15:24.622024000  8 waited
2017-10-28T21:15:24.622040000  8 release
Reader releases tasks(8)_0000000000E7C4A0
2017-10-28T21:15:24.632119000  8 get  Read  0.2
Read_Write get queueing tasks(8)_0000000000E7C4A0
Another reader tasks(8)_0000000000E7C4A0
2017-10-28T21:15:24.632139000  8 OK
2017-10-28T21:15:24.632147000  8 waiting
2017-10-28T21:15:24.832096000  1 waited
2017-10-28T21:15:24.832133000  1 release
Reader releases tasks(1)_0000000000E63F10
2017-10-28T21:15:24.842170000  6 waited
2017-10-28T21:15:24.842188000  6 release
Reader releases tasks(6)_0000000000E75880
2017-10-28T21:15:24.842214000  1 get  Read -0.1
Read_Write get queueing tasks(1)_0000000000E63F10
Another reader tasks(1)_0000000000E63F10
2017-10-28T21:15:24.842235000  1 OK
2017-10-28T21:15:24.842243000  1 waiting
2017-10-28T21:15:24.852266000  6 get  Read  0.0
Read_Write get queueing tasks(6)_0000000000E75880
Another reader tasks(6)_0000000000E75880
2017-10-28T21:15:24.852287000  6 OK
2017-10-28T21:15:24.852295000  6 waiting
2017-10-28T21:15:24.932222000  8 waited
2017-10-28T21:15:24.932238000  8 release
Reader releases tasks(8)_0000000000E7C4A0
2017-10-28T21:15:24.942304000  8 get  Read  0.5
Read_Write get queueing tasks(8)_0000000000E7C4A0
Another reader tasks(8)_0000000000E7C4A0
2017-10-28T21:15:24.942309000  2 waited
2017-10-28T21:15:24.942346000  8 OK
2017-10-28T21:15:24.942357000  2 release
Reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:24.942367000  8 waiting
2017-10-28T21:15:24.952453000  2 get  Read  0.3
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:24.952480000  2 OK
2017-10-28T21:15:24.952488000  2 waiting
2017-10-28T21:15:25.052369000  6 waited
2017-10-28T21:15:25.052384000  6 release
Reader releases tasks(6)_0000000000E75880
2017-10-28T21:15:25.062461000  6 get  Read  0.4
Read_Write get queueing tasks(6)_0000000000E75880
Another reader tasks(6)_0000000000E75880
2017-10-28T21:15:25.062481000  6 OK
2017-10-28T21:15:25.062489000  6 waiting
2017-10-28T21:15:25.162556000  6 waited
2017-10-28T21:15:25.162575000  6 release
Reader releases tasks(6)_0000000000E75880
2017-10-28T21:15:25.172668000  6 get  Read -0.1
Read_Write get queueing tasks(6)_0000000000E75880
Another reader tasks(6)_0000000000E75880
2017-10-28T21:15:25.172689000  6 OK
2017-10-28T21:15:25.172697000  6 waiting
2017-10-28T21:15:25.242313000  1 waited
2017-10-28T21:15:25.242329000  1 release
Reader releases tasks(1)_0000000000E63F10
2017-10-28T21:15:25.252407000  1 get  Read  0.0
Read_Write get queueing tasks(1)_0000000000E63F10
Another reader tasks(1)_0000000000E63F10
2017-10-28T21:15:25.252428000  1 OK
2017-10-28T21:15:25.252436000  1 waiting
2017-10-28T21:15:25.342454000  8 waited
2017-10-28T21:15:25.342491000  8 release
Reader releases tasks(8)_0000000000E7C4A0
2017-10-28T21:15:25.352573000  8 get  Read  0.4
Read_Write get queueing tasks(8)_0000000000E7C4A0
Another reader tasks(8)_0000000000E7C4A0
2017-10-28T21:15:25.352594000  8 OK
2017-10-28T21:15:25.352602000  8 waiting
2017-10-28T21:15:25.452564000  2 waited
2017-10-28T21:15:25.452584000  2 release
Reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:25.452672000  8 waited
2017-10-28T21:15:25.452686000  8 release
Reader releases tasks(8)_0000000000E7C4A0
2017-10-28T21:15:25.462663000  2 get  Read  0.0
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:25.462683000  2 OK
2017-10-28T21:15:25.462691000  2 waiting
2017-10-28T21:15:25.462762000  8 get  Read  0.2
Read_Write get queueing tasks(8)_0000000000E7C4A0
Another reader tasks(8)_0000000000E7C4A0
2017-10-28T21:15:25.462781000  8 OK
2017-10-28T21:15:25.462789000  8 waiting
2017-10-28T21:15:25.572774000  6 waited
2017-10-28T21:15:25.572789000  6 release
Reader releases tasks(6)_0000000000E75880
2017-10-28T21:15:25.582868000  6 get  Read  0.1
Read_Write get queueing tasks(6)_0000000000E75880
Another reader tasks(6)_0000000000E75880
2017-10-28T21:15:25.582889000  6 OK
2017-10-28T21:15:25.582897000  6 waiting
2017-10-28T21:15:25.662860000  8 waited
2017-10-28T21:15:25.662894000  8 release
Reader releases tasks(8)_0000000000E7C4A0
2017-10-28T21:15:25.672970000  8 get  Read  0.5
Read_Write get queueing tasks(8)_0000000000E7C4A0
Another reader tasks(8)_0000000000E7C4A0
2017-10-28T21:15:25.672993000  8 OK
2017-10-28T21:15:25.673001000  8 waiting
2017-10-28T21:15:25.752510000  1 waited
2017-10-28T21:15:25.752531000  1 release
Reader releases tasks(1)_0000000000E63F10
2017-10-28T21:15:25.762609000  1 get  Read  0.3
Read_Write get queueing tasks(1)_0000000000E63F10
Another reader tasks(1)_0000000000E63F10
2017-10-28T21:15:25.762630000  1 OK
2017-10-28T21:15:25.762638000  1 waiting
2017-10-28T21:15:25.862708000  1 waited
2017-10-28T21:15:25.862720000  1 release
Reader releases tasks(1)_0000000000E63F10
2017-10-28T21:15:25.862732000  1 terminate
2017-10-28T21:15:25.862767000  2 waited
2017-10-28T21:15:25.862783000  2 release
Reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:25.872861000  2 get  Read  0.2
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:25.872882000  2 OK
2017-10-28T21:15:25.872890000  2 waiting
2017-10-28T21:15:26.073070000  8 waited
2017-10-28T21:15:26.073087000  8 release
Reader releases tasks(8)_0000000000E7C4A0
2017-10-28T21:15:26.082972000  6 waited
2017-10-28T21:15:26.082988000  6 release
Reader releases tasks(6)_0000000000E75880
2017-10-28T21:15:26.083163000  8 get  Read  0.2
Read_Write get queueing tasks(8)_0000000000E7C4A0
Another reader tasks(8)_0000000000E7C4A0
2017-10-28T21:15:26.083181000  8 OK
2017-10-28T21:15:26.083189000  8 waiting
2017-10-28T21:15:26.093071000  6 get  Read  0.3
Read_Write get queueing tasks(6)_0000000000E75880
Another reader tasks(6)_0000000000E75880
2017-10-28T21:15:26.093095000  6 OK
2017-10-28T21:15:26.093103000  6 waiting
2017-10-28T21:15:26.172971000  2 waited
2017-10-28T21:15:26.172987000  2 release
Reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:26.183059000  2 get  Read  0.3
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:26.183080000  2 OK
2017-10-28T21:15:26.183106000  2 waiting
2017-10-28T21:15:26.383260000  8 waited
2017-10-28T21:15:26.383286000  8 release
Reader releases tasks(8)_0000000000E7C4A0
2017-10-28T21:15:26.383301000  8 terminate
2017-10-28T21:15:26.393182000  6 waited
2017-10-28T21:15:26.393198000  6 release
Reader releases tasks(6)_0000000000E75880
2017-10-28T21:15:26.393212000  6 terminate
2017-10-28T21:15:26.483178000  2 waited
2017-10-28T21:15:26.483208000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:26.493292000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:26.493316000  2 OK
2017-10-28T21:15:26.493325000  2 waiting
2017-10-28T21:15:26.993401000  2 waited
2017-10-28T21:15:26.993437000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:27.003520000  2 get  Read -0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:27.003542000  2 OK
2017-10-28T21:15:27.003550000  2 waiting
2017-10-28T21:15:27.203619000  2 waited
2017-10-28T21:15:27.203647000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:27.213722000  2 get  Read  0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:27.213746000  2 OK
2017-10-28T21:15:27.213754000  2 waiting
2017-10-28T21:15:27.513830000  2 waited
2017-10-28T21:15:27.513855000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:27.523934000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:27.523956000  2 OK
2017-10-28T21:15:27.523964000  2 waiting
2017-10-28T21:15:27.624041000  2 waited
2017-10-28T21:15:27.624061000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:27.634138000  2 get  Read  0.0
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:27.634166000  2 OK
2017-10-28T21:15:27.634175000  2 waiting
2017-10-28T21:15:28.034250000  2 waited
2017-10-28T21:15:28.034286000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:28.044367000  2 get  Read  0.2
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:28.044390000  2 OK
2017-10-28T21:15:28.044398000  2 waiting
2017-10-28T21:15:28.144463000  2 waited
2017-10-28T21:15:28.144477000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:28.154554000  2 get  Read -0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:28.154574000  2 OK
2017-10-28T21:15:28.154582000  2 waiting
2017-10-28T21:15:28.554654000  2 waited
2017-10-28T21:15:28.554694000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:28.564788000  2 get  Read  0.2
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:28.564809000  2 OK
2017-10-28T21:15:28.564817000  2 waiting
2017-10-28T21:15:28.964892000  2 waited
2017-10-28T21:15:28.964930000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:28.975011000  2 get  Read  0.0
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:28.975033000  2 OK
2017-10-28T21:15:28.975041000  2 waiting
2017-10-28T21:15:29.375116000  2 waited
2017-10-28T21:15:29.375152000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:29.385233000  2 get  Read  0.3
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:29.385256000  2 OK
2017-10-28T21:15:29.385264000  2 waiting
2017-10-28T21:15:29.585340000  2 waited
2017-10-28T21:15:29.585369000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:29.595450000  2 get  Read  0.0
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:29.595472000  2 OK
2017-10-28T21:15:29.595499000  2 waiting
2017-10-28T21:15:29.995580000  2 waited
2017-10-28T21:15:29.995616000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:30.005699000  2 get  Read  0.0
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:30.005720000  2 OK
2017-10-28T21:15:30.005728000  2 waiting
2017-10-28T21:15:30.405807000  2 waited
2017-10-28T21:15:30.405841000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:30.415924000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:30.415949000  2 OK
2017-10-28T21:15:30.415957000  2 waiting
2017-10-28T21:15:30.916029000  2 waited
2017-10-28T21:15:30.916066000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:30.926148000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:30.926170000  2 OK
2017-10-28T21:15:30.926178000  2 waiting
2017-10-28T21:15:31.026251000  2 waited
2017-10-28T21:15:31.026271000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:31.036349000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:31.036370000  2 OK
2017-10-28T21:15:31.036378000  2 waiting
2017-10-28T21:15:31.436457000  2 waited
2017-10-28T21:15:31.436496000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:31.446579000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:31.446603000  2 OK
2017-10-28T21:15:31.446611000  2 waiting
2017-10-28T21:15:31.746681000  2 waited
2017-10-28T21:15:31.746717000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:31.756798000  2 get  Read  0.5
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:31.756820000  2 OK
2017-10-28T21:15:31.756828000  2 waiting
2017-10-28T21:15:32.056900000  2 waited
2017-10-28T21:15:32.056916000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:32.066994000  2 get  Read  0.0
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:32.067014000  2 OK
2017-10-28T21:15:32.067022000  2 waiting
2017-10-28T21:15:32.167094000  2 waited
2017-10-28T21:15:32.167110000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:32.177187000  2 get Write  0.3
Read_Write get queueing tasks(2)_0000000000E68040
Writer has got lock tasks(2)_0000000000E68040
2017-10-28T21:15:32.177207000  2 OK
2017-10-28T21:15:32.177214000  2 waiting
2017-10-28T21:15:32.477286000  2 waited
2017-10-28T21:15:32.477325000  2 release
Writer releases tasks(2)_0000000000E68040
2017-10-28T21:15:32.487402000  2 get  Read  0.3
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:32.487424000  2 OK
2017-10-28T21:15:32.487432000  2 waiting
2017-10-28T21:15:32.687509000  2 waited
2017-10-28T21:15:32.687547000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:32.697628000  2 get  Read -0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:32.697651000  2 OK
2017-10-28T21:15:32.697659000  2 waiting
2017-10-28T21:15:32.897731000  2 waited
2017-10-28T21:15:32.897745000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:32.907822000  2 get  Read  0.0
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:32.907842000  2 OK
2017-10-28T21:15:32.907850000  2 waiting
2017-10-28T21:15:33.307919000  2 waited
2017-10-28T21:15:33.307952000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:33.318032000  2 get  Read  0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:33.318071000  2 OK
2017-10-28T21:15:33.318080000  2 waiting
2017-10-28T21:15:33.718160000  2 waited
2017-10-28T21:15:33.718215000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:33.728307000  2 get  Read  0.3
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:33.728329000  2 OK
2017-10-28T21:15:33.728337000  2 waiting
2017-10-28T21:15:34.228412000  2 waited
2017-10-28T21:15:34.228445000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:34.238526000  2 get  Read -0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:34.238548000  2 OK
2017-10-28T21:15:34.238556000  2 waiting
2017-10-28T21:15:34.538629000  2 waited
2017-10-28T21:15:34.538647000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:34.548728000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:34.548752000  2 OK
2017-10-28T21:15:34.548761000  2 waiting
2017-10-28T21:15:34.948840000  2 waited
2017-10-28T21:15:34.948878000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:34.958963000  2 get Write  0.2
Read_Write get queueing tasks(2)_0000000000E68040
Writer has got lock tasks(2)_0000000000E68040
2017-10-28T21:15:34.958987000  2 OK
2017-10-28T21:15:34.958995000  2 waiting
2017-10-28T21:15:35.259070000  2 waited
2017-10-28T21:15:35.259088000  2 release
Writer releases tasks(2)_0000000000E68040
2017-10-28T21:15:35.269165000  2 get  Read -0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:35.269186000  2 OK
2017-10-28T21:15:35.269194000  2 waiting
2017-10-28T21:15:35.569274000  2 waited
2017-10-28T21:15:35.569311000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:35.579396000  2 get  Read  0.0
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:35.579420000  2 OK
2017-10-28T21:15:35.579428000  2 waiting
2017-10-28T21:15:35.879506000  2 waited
2017-10-28T21:15:35.879541000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:35.889623000  2 get  Read  0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:35.889644000  2 OK
2017-10-28T21:15:35.889652000  2 waiting
2017-10-28T21:15:36.189721000  2 waited
2017-10-28T21:15:36.189744000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:36.199823000  2 get  Read  0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:36.199844000  2 OK
2017-10-28T21:15:36.199852000  2 waiting
2017-10-28T21:15:36.599930000  2 waited
2017-10-28T21:15:36.599964000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:36.610050000  2 get  Read  0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:36.610076000  2 OK
2017-10-28T21:15:36.610084000  2 waiting
2017-10-28T21:15:37.010162000  2 waited
2017-10-28T21:15:37.010200000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:37.020282000  2 get  Read  0.3
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:37.020305000  2 OK
2017-10-28T21:15:37.020313000  2 waiting
2017-10-28T21:15:37.420390000  2 waited
2017-10-28T21:15:37.420417000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:37.430498000  2 get  Read  0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:37.430519000  2 OK
2017-10-28T21:15:37.430527000  2 waiting
2017-10-28T21:15:37.730596000  2 waited
2017-10-28T21:15:37.730633000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:37.740713000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:37.740754000  2 OK
2017-10-28T21:15:37.740762000  2 waiting
2017-10-28T21:15:38.140840000  2 waited
2017-10-28T21:15:38.140862000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:38.150942000  2 get  Read  0.5
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:38.150963000  2 OK
2017-10-28T21:15:38.150972000  2 waiting
2017-10-28T21:15:38.551046000  2 waited
2017-10-28T21:15:38.551084000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:38.561169000  2 get  Read  0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:38.561193000  2 OK
2017-10-28T21:15:38.561201000  2 waiting
2017-10-28T21:15:38.761271000  2 waited
2017-10-28T21:15:38.761315000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:38.771407000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:38.771429000  2 OK
2017-10-28T21:15:38.771437000  2 waiting
2017-10-28T21:15:39.171511000  2 waited
2017-10-28T21:15:39.171539000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:39.181620000  2 get  Read  0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:39.181645000  2 OK
2017-10-28T21:15:39.181653000  2 waiting
2017-10-28T21:15:39.381735000  2 waited
2017-10-28T21:15:39.381777000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:39.391859000  2 get  Read  0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:39.391881000  2 OK
2017-10-28T21:15:39.391889000  2 waiting
2017-10-28T21:15:39.691968000  2 waited
2017-10-28T21:15:39.692008000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:39.702089000  2 get  Read -0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:39.702111000  2 OK
2017-10-28T21:15:39.702119000  2 waiting
2017-10-28T21:15:40.002188000  2 waited
2017-10-28T21:15:40.002214000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:40.012293000  2 get Write  0.3
Read_Write get queueing tasks(2)_0000000000E68040
Writer has got lock tasks(2)_0000000000E68040
2017-10-28T21:15:40.012314000  2 OK
2017-10-28T21:15:40.012322000  2 waiting
2017-10-28T21:15:40.412390000  2 waited
2017-10-28T21:15:40.412415000  2 release
Writer releases tasks(2)_0000000000E68040
2017-10-28T21:15:40.422496000  2 get  Read  0.0
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:40.422517000  2 OK
2017-10-28T21:15:40.422525000  2 waiting
2017-10-28T21:15:40.822601000  2 waited
2017-10-28T21:15:40.822637000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:40.832719000  2 get  Read -0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:40.832741000  2 OK
2017-10-28T21:15:40.832749000  2 waiting
2017-10-28T21:15:41.132824000  2 waited
2017-10-28T21:15:41.132845000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:41.142924000  2 get  Read -0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:41.142945000  2 OK
2017-10-28T21:15:41.142953000  2 waiting
2017-10-28T21:15:41.443034000  2 waited
2017-10-28T21:15:41.443077000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:41.453160000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:41.453184000  2 OK
2017-10-28T21:15:41.453192000  2 waiting
2017-10-28T21:15:41.753267000  2 waited
2017-10-28T21:15:41.753306000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:41.763387000  2 get  Read -0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:41.763426000  2 OK
2017-10-28T21:15:41.763434000  2 waiting
2017-10-28T21:15:41.863510000  2 waited
2017-10-28T21:15:41.863525000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:41.873605000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:41.873629000  2 OK
2017-10-28T21:15:41.873637000  2 waiting
2017-10-28T21:15:42.273708000  2 waited
2017-10-28T21:15:42.273741000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:42.283819000  2 get  Read  0.3
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:42.283844000  2 OK
2017-10-28T21:15:42.283853000  2 waiting
2017-10-28T21:15:42.583929000  2 waited
2017-10-28T21:15:42.583954000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:42.594034000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:42.594056000  2 OK
2017-10-28T21:15:42.594065000  2 waiting
2017-10-28T21:15:42.794142000  2 waited
2017-10-28T21:15:42.794182000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:42.804264000  2 get  Read -0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:42.804287000  2 OK
2017-10-28T21:15:42.804296000  2 waiting
2017-10-28T21:15:43.104374000  2 waited
2017-10-28T21:15:43.104400000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:43.114481000  2 get  Read  0.0
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:43.114504000  2 OK
2017-10-28T21:15:43.114513000  2 waiting
2017-10-28T21:15:43.314585000  2 waited
2017-10-28T21:15:43.314605000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:43.324684000  2 get  Read  0.0
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:43.324707000  2 OK
2017-10-28T21:15:43.324715000  2 waiting
2017-10-28T21:15:43.724984000  2 waited
2017-10-28T21:15:43.725023000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:43.735103000  2 get  Read -0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:43.735134000  2 OK
2017-10-28T21:15:43.735143000  2 waiting
2017-10-28T21:15:44.035217000  2 waited
2017-10-28T21:15:44.035255000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:44.045346000  2 get  Read  0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:44.045369000  2 OK
2017-10-28T21:15:44.045377000  2 waiting
2017-10-28T21:15:44.245450000  2 waited
2017-10-28T21:15:44.245471000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:44.255551000  2 get  Read  0.5
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:44.255574000  2 OK
2017-10-28T21:15:44.255582000  2 waiting
2017-10-28T21:15:44.355662000  2 waited
2017-10-28T21:15:44.355703000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:44.365786000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:44.365812000  2 OK
2017-10-28T21:15:44.365821000  2 waiting
2017-10-28T21:15:44.565899000  2 waited
2017-10-28T21:15:44.565930000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:44.576016000  2 get  Read  0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:44.576041000  2 OK
2017-10-28T21:15:44.576050000  2 waiting
2017-10-28T21:15:44.876120000  2 waited
2017-10-28T21:15:44.876158000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:44.886240000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:44.886281000  2 OK
2017-10-28T21:15:44.886290000  2 waiting
2017-10-28T21:15:45.186362000  2 waited
2017-10-28T21:15:45.186384000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:45.196462000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:45.196483000  2 OK
2017-10-28T21:15:45.196492000  2 waiting
2017-10-28T21:15:45.296562000  2 waited
2017-10-28T21:15:45.296585000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:45.306664000  2 get  Read  0.5
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:45.306685000  2 OK
2017-10-28T21:15:45.306693000  2 waiting
2017-10-28T21:15:45.706766000  2 waited
2017-10-28T21:15:45.706804000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:45.706821000  2 terminate
2017-10-28T21:15:50.729534000 Main Deadlock detected, aborting
2017-10-28T21:15:50.729586000 Main Done

Task 7 did not terminate.
Last report of it was "21:15:21.149875000  7 get  Read  0.2"
At this time, 1 has got the lock for read, 3 is requesting it for write and
the other tasks are queueing for read or write (7 is queueing for read).
When 1 releases the lock: 017-10-28T21:15:21.349976000  1 release
the log of swapping shows that task 4, requesting for write, triggers the
swapping: Start swapping tasks(4)_0000000000E6EC60
At that time, all the queueing tasks are logged as being swapped except 7,
and task 7 seems to be blocked somewhere and is never activated.

Can you reproduce it? On Windows?
Is the bug in the test program, or in the mutex implementation, in Linux, or in Gnat?

Thanks

^ permalink raw reply	[relevance 1%]

* Re: How to make tasks to run in parallel
  2017-10-17  4:58  5% How to make tasks to run in parallel reinert
@ 2017-10-17  6:17  5% ` Per Sandberg
  0 siblings, 0 replies; 200+ results
From: Per Sandberg @ 2017-10-17  6:17 UTC (permalink / raw)


It won't run in parallel since all the computations are done within the 
roundevouz where both tasks are are running "in the same thread".
And also why a private Real type when there is a general Float.
Have a look on the updated code.
/P
----------------------------
with Ada.Text_IO;
with Ada.Integer_Text_IO;
with Ada.Float_Text_IO;
with Ada.Numerics.Elementary_Functions;

procedure Main is

    use Ada.Text_IO;
    use Ada.Integer_Text_IO;
    use Ada.Float_Text_IO;
    use Ada.Numerics.Elementary_Functions;

    N : constant Integer := 10_000_000;

    -- 
---------------------------------------------------------------------------
    task type Test1_T (A : access Float);

    task body Test1_T is
       X : Float := A.all;
    begin
       -- stupid time consuming loop:
       for I in 1 .. N loop
          X := X + Float (I) / Float (N);
          X := 0.5 * X + 1.0 + Sin (X) * Cos (X) + Sin (X) + Cos (X) +
            Sin (X) * Sin (X) + Cos (X) * Cos (X);
       end loop;
       New_Line; Put ("test1 x:"); Put (X, 4, 16, 0); New_Line (1);
    end Test1_T;
    -- 
---------------------------------------------------------------------------
    task type Test2_T is
       entry Run1 (A : in Float);
    end Test2_T;

    task body Test2_T is
       X : Float;
    begin
       accept Run1 (A : in Float) do
          X := A;
       end Run1;
       -- stupid time consuming loop:
       for I in 1 .. N loop
          X := X + Float (I) / Float (N);
          X := 0.5 * X + 1.0 + Sin (X) * Cos (X) + Sin (X) + Cos (X) +
            Sin (X) * Sin (X) + Cos (X) * Cos (X);
       end loop;
       New_Line; Put ("test2 x:"); Put (X, 4, 16, 0); New_Line (1);
    end Test2_T;

    X     : aliased Float;
    Y     : Float;
    Dx, Dy : constant := 0.5;

    Test1 : array (1 .. 4) of access Test1_T;
    Test2 : array (1 .. 4) of access Test2_T;
    -- 
---------------------------------------------------------------------------

begin

    -- This goes in parallel:
    X := 1.0;
    for E of Test1 loop
       X := X + Dx;
       Put_Line (" Test1: ");
       E := new Test1_T (A => X'Access);
    end loop;

    Y := 1.0;
    for E of Test2 loop
       Y := Y + Dy;
       Put_Line (" Test2: ");
       E := new Test2_T;
       E.Run1 (Y);
    end loop;

end Main;
---------------------------------------------------------------------





Den 2017-10-17 kl. 06:58, skrev reinert:
> Hi,
> 
> The test program below includes two tasks. The first task gets an "argument" (input data) via a discriminant. The other task gets data via entry/accept. The first task runs easily in parallel. The other not.
> 
> I would prefer to enter data via entry/accept. But is it possible without giving up parallel processing? I feel it is something I should understand better here :-)
> 
> reinert
> 
> 
> with Text_IO;       use Text_IO;
> with Ada.Numerics.Generic_Elementary_Functions;
> with Ada.Text_IO;
> procedure ttest1 is
>    type Real is new Float;
>    package Flt_Io is new Text_IO.Float_Io   (Real);
>    package Int_Io is new Text_IO.Integer_Io (Integer);
>    package E_F is new Ada.Numerics.Generic_Elementary_Functions (Real);
>    use E_F,Flt_Io,Int_Io;
> 
>    N : constant Integer := 10_000_000;
> 
> -- ---------------------------------------------------------------------------
>    task type test1_t(a : access real);
> 
>    task body test1_t is
>        x : real := a.all;
>    begin
> -- stupid time consuming loop:
>        for I in 1 .. N loop
>            x := x + Real(I)/Real(N);
>            x := 0.5*x + 1.0 + sin(x)*cos(x) + sin(x) + cos(x) +
>                               sin(x)*sin(x) + cos(x)*cos(x);
>        end loop;
>        new_line;Put("test1 x:");Put (x,4,16,0); New_Line (1);
>    end test1_t;
> -- ---------------------------------------------------------------------------
>    task type test2_t is
>       entry run1(a : in real);
>    end test2_t;
> 
>    task body test2_t is
>      x : real;
>    begin
>        accept run1(a : in real) do
>          x := a;
> -- stupid time consuming loop:
>          for I in 1 .. N loop
>              x := x + Real(I)/Real(N);
>              x := 0.5*x + 1.0 + sin(x)*cos(x) + sin(x) + cos(x) +
>                               sin(x)*sin(x) + cos(x)*cos(x);
>          end loop;
>          new_line;Put("test2 x:");Put (x,4,16,0); New_Line (1);
>          return;
>        end run1;
>    end test2_t;
> 
>    x : aliased real;
>    y : real;
>    dx,dy : constant := 0.5;
> 
>    test1 : array(1..4) of access test1_t;
>    test2 : array(1..4) of access test2_t;
> -- ---------------------------------------------------------------------------
> 
> begin
> 
> -- This goes in parallel:
>       x := 1.0;
>       for e of test1 loop
>           x := x + dx;
>           Put_Line(" Test1: ");
>           e := new test1_t(a => x'access);
>       end loop;
> 
> -- This goes *not* in parallel (why?):
>       y := 1.0;
>       for e of test2 loop
>           y := y + dy;
>           Put_Line(" Test2: ");
>           e := new test2_t;
>           e.run1(y);
>       end loop;
> 
> end ttest1;
> 


^ permalink raw reply	[relevance 5%]

* How to make tasks to run in parallel
@ 2017-10-17  4:58  5% reinert
  2017-10-17  6:17  5% ` Per Sandberg
  0 siblings, 1 reply; 200+ results
From: reinert @ 2017-10-17  4:58 UTC (permalink / raw)


Hi,

The test program below includes two tasks. The first task gets an "argument" (input data) via a discriminant. The other task gets data via entry/accept. The first task runs easily in parallel. The other not.

I would prefer to enter data via entry/accept. But is it possible without giving up parallel processing? I feel it is something I should understand better here :-)

reinert


with Text_IO;       use Text_IO;
with Ada.Numerics.Generic_Elementary_Functions;
with Ada.Text_IO;
procedure ttest1 is
  type Real is new Float;
  package Flt_Io is new Text_IO.Float_Io   (Real);
  package Int_Io is new Text_IO.Integer_Io (Integer);
  package E_F is new Ada.Numerics.Generic_Elementary_Functions (Real);
  use E_F,Flt_Io,Int_Io;

  N : constant Integer := 10_000_000;

-- ---------------------------------------------------------------------------
  task type test1_t(a : access real);

  task body test1_t is
      x : real := a.all;
  begin
-- stupid time consuming loop:
      for I in 1 .. N loop
          x := x + Real(I)/Real(N);
          x := 0.5*x + 1.0 + sin(x)*cos(x) + sin(x) + cos(x) +
                             sin(x)*sin(x) + cos(x)*cos(x);
      end loop;
      new_line;Put("test1 x:");Put (x,4,16,0); New_Line (1);
  end test1_t;
-- ---------------------------------------------------------------------------
  task type test2_t is
     entry run1(a : in real);
  end test2_t;

  task body test2_t is
    x : real;
  begin
      accept run1(a : in real) do
        x := a;
-- stupid time consuming loop:
        for I in 1 .. N loop
            x := x + Real(I)/Real(N);
            x := 0.5*x + 1.0 + sin(x)*cos(x) + sin(x) + cos(x) +
                             sin(x)*sin(x) + cos(x)*cos(x);
        end loop;
        new_line;Put("test2 x:");Put (x,4,16,0); New_Line (1);
        return;
      end run1;
  end test2_t;

  x : aliased real;
  y : real;
  dx,dy : constant := 0.5;

  test1 : array(1..4) of access test1_t;
  test2 : array(1..4) of access test2_t;
-- ---------------------------------------------------------------------------

begin

-- This goes in parallel:
     x := 1.0;
     for e of test1 loop
         x := x + dx;
         Put_Line(" Test1: ");
         e := new test1_t(a => x'access);
     end loop;

-- This goes *not* in parallel (why?):
     y := 1.0;
     for e of test2 loop
         y := y + dy;
         Put_Line(" Test2: ");
         e := new test2_t;
         e.run1(y);
     end loop;

end ttest1;


^ permalink raw reply	[relevance 5%]

* Re: Community Input for the Maintenance and Revision of the Ada Programming Language
  @ 2017-09-09 14:48  3%           ` G.B.
  0 siblings, 0 replies; 200+ results
From: G.B. @ 2017-09-09 14:48 UTC (permalink / raw)


On 06.09.17 17:02, Johan Söderlind Åström wrote:
> I do not know how Ada accesses a array element internally. But a zero indexed array must be cheaper than a custom indexed array, see:
>
> Accessing nth element from zero indexed array:
> (base_address + index*element_size).
>
> Accessing nth element from a custom indexed array:
> (base_address + (index - first)*element_size)
>
> I do not think that accessing a element from a array is a complicated thing and starting from a zero indexed array is even simpler, then why would a compiler not guarantee such a simple thing to work?

It seems to work well the way it is?
Is it a certainty that your assumptions describe
how our processors are working?

So, I checked, starting from a naive Average function, and
another Average_0 function. Both perform the same algorithm
with the exception of the parameter types: these are,
respectively, an array type with Index range <> and
a zero-based fixed size array type. (Index starts at 0.)

This is the loop body of both functions:

       for V : Likeness of Difference loop
          Result := Result + V / Likeness'Base (Difference'Length);
       end loop;

where Likeness is like Uniformly_Distributed from
Ada.Numerics.Float_Random, and Difference is an array.

The difference in the resulting loop bodies, on Intel,
for Average and Average_0 is this, when passing options
-O2 -gnatp -fno-inline to GNAT:

L17:
	addq	$1, %rax
	movss	(%rcx,%rax,4), %xmm1
	cmpq	%rdx, %rax
	divss	%xmm2, %xmm1
	addss	%xmm1, %xmm0
	jne	L17

L45:
	movss	(%rdi), %xmm1
	addq	$4, %rdi
	cmpq	%rax, %rdi
	divss	%xmm2, %xmm1
	addss	%xmm1, %xmm0
	jne	L45

When I have the functions called 100_000 times, the calls
result in execution time of some 50 seconds for either function.

There are 6 instructions for either 0-based or free bounds.

Maybe the loop isn't sufficiently dominated by addressing
from one or two registers, given DIVSS?

But first, using a modular type as the index type in place
of a range type starting at 0, I get

L24:
	movl	%eax, %edx
	addq	$1, %rax
	subq	%rsi, %rdx
	cmpq	%rax, %rcx
	movss	(%rdi,%rdx,4), %xmm1
	divss	%xmm2, %xmm1
	addss	%xmm1, %xmm0
	jne	L24

L59:
	movss	(%rdi,%rax,4), %xmm1
	addq	$1, %rax
	cmpq	$100000, %rax
	divss	%xmm2, %xmm1
	addss	%xmm1, %xmm0
	jne	L59

Still, no difference. So, using Sum now, here is the loop body
of Sum and Sum_0:

       for V : Likeness of Difference loop
          Result := Result + Float (V);
       end loop;


L63:
	movl	%eax, %edx
	addq	$1, %rax
	subq	%rsi, %rdx
	cmpq	%rax, %rcx
	addss	(%rdi,%rdx,4), %xmm0
	jne	L63

L67:
	addss	(%rdi,%rax,4), %xmm0
	addq	$1, %rax
	cmpq	$100000, %rax
	jne	L67
	ret

This result is independent of the choice of index type.
I had expected the first block to be slower than
the second due to SUB, but was wrong, seemingly.
Durations are around 10 seconds now.

So, if I haven't made some other stupid mistake, 0-based
arrays appear to be a non-issue, at least on Intel CPUs.


^ permalink raw reply	[relevance 3%]

* ANN: Cortex GNAT RTS 2017-08-08
@ 2017-08-08 13:04  4% Simon Wright
  0 siblings, 0 replies; 200+ results
From: Simon Wright @ 2017-08-08 13:04 UTC (permalink / raw)


This release is available at Github[1] - note the move from Sourceforge.

The main motivation for the last two releases has been to support
AdaCore's Certyflie[2], or at least my fork at [3].

There have been compiler interface changes, so some patching will be
required[4] if you're using GNAT GPL 2016 or 2017.

New features:

* Ada.Numerics.* (except random numbers).
* Interfaces.C.Extensions.
* Ada.Real_Time.Timing_Events.
* All free store (bar a 2048-byte allowance for startup and interrupts)
  is available for heap allocation.
* Sequential elaboration (with the configuration pragma
  Partition_Elaboration_Policy (Sequential)) is supported.
* type'Image() and object'Img are supported.

[1] https://github.com/simonjwright/cortex-gnat-rts/releases
[2] https://github.com/AdaCore/Certyflie
[3] https://github.com/simonjwright/Certyflie
[4] https://github.com/simonjwright/cortex-gnat-rts/blob/master/INSTALL.md#compatibility

^ permalink raw reply	[relevance 4%]

* Re: Can't work out how to use with Ada.Numerics.Discrete_Random with SPARK 2014
  2017-06-30  7:28  6% ` Simon Wright
@ 2017-06-30 11:38 11%   ` digitig
  0 siblings, 0 replies; 200+ results
From: digitig @ 2017-06-30 11:38 UTC (permalink / raw)


On Friday, June 30, 2017 at 8:28:27 AM UTC+1, Simon Wright wrote:
> digitig writes:
> 
> > package body Main
> > with SPARK_Mode => On
> > is
> >    procedure Test is
> >       subtype Die is Integer range 1 .. 6;
> >       subtype Dice is Integer range 2*Die'First .. 2*Die'Last;
> >       package Random_Die is new Ada.Numerics.Discrete_Random (Die);
> 
> (SPARK GPL 2017) move these declarations up to package level .. then,
> 
> >       use Random_Die;
> >       G : Generator;
> 
>  "Generator" is not allowed in SPARK
>  violation of aspect SPARK_Mode at line xx
> 
> >       D : Dice;
> >    begin
> >       Reset (G);  -- Start the generator in a unique state in each run
> >       loop
> >          -- Roll a pair of dice; sum and process the results
> >          D := Random(G) + Random(G);
> 
>  "Result_Subtype" is not allowed in SPARK
>  violation of aspect SPARK_Mode at line xx
> 
> >          Ada.Text_IO.Put_Line(D'Image);
> >       end loop;
> >    end Test;
> > end Main;

But at least I can then turn SPARK-Mode off for the Test procedure, which means with a bit of shuffling I should be able to localise the part where SPARK-Mode is off to just the random number generator. Thanks.

I'm puzzled by why I have to do that, though, when Ada.Numerics.Discrete_Random itself turns SPARK_Mode off.

^ permalink raw reply	[relevance 11%]

* Re: Can't work out how to use with Ada.Numerics.Discrete_Random with SPARK 2014
  2017-06-30  1:15 12% Can't work out how to use with Ada.Numerics.Discrete_Random with SPARK 2014 digitig
@ 2017-06-30  7:28  6% ` Simon Wright
  2017-06-30 11:38 11%   ` digitig
  0 siblings, 1 reply; 200+ results
From: Simon Wright @ 2017-06-30  7:28 UTC (permalink / raw)


digitig <digitig@gmail.com> writes:

> package body Main
> with SPARK_Mode => On
> is
>    procedure Test is
>       subtype Die is Integer range 1 .. 6;
>       subtype Dice is Integer range 2*Die'First .. 2*Die'Last;
>       package Random_Die is new Ada.Numerics.Discrete_Random (Die);

(SPARK GPL 2017) move these declarations up to package level .. then,

>       use Random_Die;
>       G : Generator;

 "Generator" is not allowed in SPARK
 violation of aspect SPARK_Mode at line xx

>       D : Dice;
>    begin
>       Reset (G);  -- Start the generator in a unique state in each run
>       loop
>          -- Roll a pair of dice; sum and process the results
>          D := Random(G) + Random(G);

 "Result_Subtype" is not allowed in SPARK
 violation of aspect SPARK_Mode at line xx

>          Ada.Text_IO.Put_Line(D'Image);
>       end loop;
>    end Test;
> end Main;

^ permalink raw reply	[relevance 6%]

* Can't work out how to use with Ada.Numerics.Discrete_Random with SPARK 2014
@ 2017-06-30  1:15 12% digitig
  2017-06-30  7:28  6% ` Simon Wright
  0 siblings, 1 reply; 200+ results
From: digitig @ 2017-06-30  1:15 UTC (permalink / raw)


In main.ads I have:

package Main
with SPARK_Mode => On
is
   procedure Test;
end Main;

In main.adb I have:

with Ada.Numerics.Discrete_Random;
with Ada.Text_IO;
package body Main
with SPARK_Mode => On
is
   procedure Test is
      subtype Die is Integer range 1 .. 6;
      subtype Dice is Integer range 2*Die'First .. 2*Die'Last;
      package Random_Die is new Ada.Numerics.Discrete_Random (Die);
      use Random_Die;
      G : Generator;
      D : Dice;
   begin
      Reset (G);  -- Start the generator in a unique state in each run
      loop
         -- Roll a pair of dice; sum and process the results
         D := Random(G) + Random(G);
         Ada.Text_IO.Put_Line(D'Image);
      end loop;
   end Test;
end Main;

Running SPARK | Examine all sources from GPS gives me the error:

        9:7 "Random_Die" is not a library-level package
        9:7 incorrect placement of aspect "Spark_Mode"
        9:7 instantiation error at a-nudira.ads:45

Line 9 is:

      package Random_Die is new Ada.Numerics.Discrete_Random (Die);

But the error points into a line in the GNAT library, in a-nudira.ads that simply says

        SPARK_Mode => Off

I'm completely bewildered here - what's wrong with my code here (other than it being a toy example)? And how *do* I use Ada.Numerics.Discrete_Random in conjunction with SPARK?

^ permalink raw reply	[relevance 12%]

* Re: Help needed - "Storage_Error stack overflow or erroneous memory access"
  @ 2017-06-19  4:53  5%             ` reinert
  0 siblings, 0 replies; 200+ results
From: reinert @ 2017-06-19  4:53 UTC (permalink / raw)


OK, for those having interest:

I have somehow sorted out the problem. 
The lesson learned is that I may have done something wrong when using "with invariant .." and the compiler error message could be more helpful for programmers like me :-) 

Here is a test program illustrating. It compiles without error on my debian 8.8 (jessie) machine, but the debian 9 (stretch) gives a cryptic error message.
Could anybody confirm? And maybe elaborate?

with frame1;         use frame1;
procedure c0 is
   df : df_t;
begin
   df.center0 (True);
end c0;

-- package:

with Ada.Numerics.Generic_Real_Arrays;

package frame1 is

   subtype real is float;

   package gra is new Ada.Numerics.Generic_Real_Arrays (real);
   use gra;

   type frame_t is tagged private;

   procedure center0 (frame : in out frame_t; b : Boolean);

   type df_t is new frame_t with private;

private

   type frame_t is tagged record
      a, b                           : Boolean := False;
      r_a, r_b                       : real_vector(1..2);
      set_modus                      : Boolean := False;
      dynamic_frame1, dynamic_frame2 : real_vector (1 .. 2);
      center0                        : Boolean := False;
      active1                        : Boolean := False;
      w1,w2                          : real_vector(1..2);
   end record with
       type_invariant =>
             ((if
               frame_t.set_modus
         then
           frame_t.dynamic_frame1 (1) <= frame_t.dynamic_frame2 (1) and
           frame_t.dynamic_frame1 (2) >= frame_t.dynamic_frame2 (2)));

   type df_t is new frame_t with record
      focus1 : Boolean              := False;
   end record;

end frame1;

package body frame1 is

   procedure center0 (frame : in out frame_t; b : Boolean) is
   begin
      frame.center0 := b;
   end center0;

end frame1;




~        

^ permalink raw reply	[relevance 5%]

* Re: Arrays in Ada 2020
  @ 2017-06-18 12:06  5%     ` Robert Eachus
  0 siblings, 0 replies; 200+ results
From: Robert Eachus @ 2017-06-18 12:06 UTC (permalink / raw)


On Saturday, June 17, 2017 at 11:00:15 PM UTC-4, Nasser M. Abbasi wrote:
> On 6/17/2017 9:14 PM, Ivan Levashev wrote:
> > 
> > FYI Ada 2020 is about to bring some improvements:
> > 
> > http://www.ada-auth.org/standards/2xrm/html/RM-4-3-3.html
> > 
> >> G : constant Matrix :=
> >>      (for I in 1 .. 4 =>
> >>         (for J in 1 .. 4 =>
> >>            (if I = J then 1.0 else 0.0))); -- Identity matrix
> > 
> > Best Regards,
> > Ivan Levashev,
> > Barnaul
> 
> That is nice. But still too much code for such common operation.

What about:

with Ada.Numerics.Generic_Real_Arrays;
procedure Main is
   package My_Arrays is new Ada.Numerics.Generic_Real_Arrays(Long_Float);
   use My_Arrays;
   Identity_4: Real_Matrix := Unit_Matrix(4); 
begin null; end Main;

On a different but related subject, the body of Unit_Matrix should look like:
    function Unit_Matrix (Order           : Positive;
                         First_1, First_2 : Integer := 1)
                                            return Real_Matrix is
      Result: Real_Matrix(First_1..First_1+Order,
                     First_2..First_2+Order) := (others => 
                                                (others => 0.0));
   begin
     for I in First_1..First_1+Order loop
        Result(I, I-First_1+First_2) := 1.0;
     end loop;
     return Result;
   end Unit_Matrix;

On modern virtual memory machines, new space (as opposed to reused stack space) is cleared to zeros and the compiler knows it.  If you are allocating a large chunk of memory (in theory on the stack), the compiler can grab new memory and put a pointer on the stack.  If you are working with large matrices, you either expect this to happen or handle it yourself.  Setting the diagonal values to 1.0 is an operation repeated Order times not Order squared times, so let the compiler do the zeros as fast as possible, then worry about the ones.

Oh, and the compiler should create Result in place, rather than copying back.  The fact that the view of the object that Unit_Matrix is assigned to may be constant won't affect things, the view of Result inside Unix_Matrix is not constant.

^ permalink raw reply	[relevance 5%]

* Re: Portable memory barrier?
  @ 2017-05-09 22:26  4%                   ` Jere
  0 siblings, 0 replies; 200+ results
From: Jere @ 2017-05-09 22:26 UTC (permalink / raw)


On Tuesday, May 9, 2017 at 12:32:38 AM UTC-4, Robert Eachus wrote:
> > I am still digesting some of this, so forgive the simple question:
> > 
> > What prevents the last 3 lines from being reordered like this:
> > r1 := r1 + 1;
> > (Write_Index'Address) := r1;
> > (r3) := r4;
> 
> See above.  Writes cannot be moved past writes.  In practice the write pipe does some magic combining writes to the same cache line, etc.  But it maintains the order on writes to cache.  If you have the right equipment you can peek and see that the writes to main memory are misordered, or even missing.  But without a signal analyzer or some such, you can't peek at main memory bypassing the cache. 

Again, thanks for the responses.

I wanted to get back to this.  I wanted to do some testing, so I generated an 
example of two tasks that each update an index and then copy another (2 stores 
and a load).  I ran it on two different intel processors (all I had to test 
with): i7-4702MQ and i7-6700.  In both cases, there was CPU instruction 
reordering on the two stores (generated assembly had them in the correct order).  
ON the first processor I was running GCC 4.1.2 and pragma Atomic was not working 
as Randy described, so I had to insert a makeshift fence (I declared a protected 
object), which prevented the reordering.  On the second processor I was running 
GCC 4.9.3 which properly inserted synchronization primitives to prevent CPU 
instruction reordering, but if I enabled the GNAT pragma to turn off those 
primitives, it operated like the GCC 4.1.2 version.

I'll put the test code below.  I hope it illustrates the issue I was trying
to describe earlier.

Test_Reorder.ads
********************************************************************************
package Test_Reorder is
   procedure Run;
end Test_Reorder;


Test_Reorder.adb
********************************************************************************
pragma Ada_95;

with Ada.Numerics.Discrete_Random;
with Ada.Text_IO;

package body Test_Reorder is
   
   X      : Integer := 0; 
   Y      : Integer := 0; 
   X_Copy : Integer := 0; 
   Y_Copy : Integer := 0; 
   
   -- In GCC 4.9.3, these pragmas are sufficient
   -- to prevent reordering.  Not in GCC 4.1.2 though
   pragma Atomic(X);
   pragma Atomic(Y);     
   pragma Atomic(X_Copy);
   pragma Atomic(Y_Copy);
   
   -- Uncomment these to get CPU instruction reordering in 4.9.3
--     pragma Disable_Atomic_Synchronization(X);
--     pragma Disable_Atomic_Synchronization(Y);
--     pragma Disable_Atomic_Synchronization(X_Copy);
--     pragma Disable_Atomic_Synchronization(Y_Copy);
   
   package Positive_Random is new Ada.Numerics.Discrete_Random(Positive);
   
   Generator : Positive_Random.Generator;
   
   function Random_Number return Natural is
   begin
      return Positive_Random.Random(Generator) mod 8;
   end Random_Number;
   
   task Task1 is
      entry Start;
      entry Stop;
   end Task1;
   
   task Task2 is
      entry Start;
      entry Stop;
   end Task2;
   
   task body Task1 is
   begin
      loop
         accept Start;
         -- Delay a random amount of time
         while Random_Number /= 0 loop
            null;
         end loop;
         
         X := 1;  -- In GCC 4.1.2 I need to insert a fence after this
         Y_Copy := Y;
         
         accept Stop;         
      end loop;
   end Task1;
   
   task body Task2 is
   begin
      loop
         accept Start;
         -- Delay a random amount of time
         while Random_Number /= 0 loop
            null;
         end loop;
         
         Y := 1;   -- In GCC 4.1.2 I need to insert a fence after this
         X_Copy := X;
         
         accept Stop;         
      end loop;
   end Task2;
   
   procedure Run is 
      Detections : Natural := 0;
      Iterations : Natural := 0;
   begin
      Positive_Random.Reset(Generator);
      
      loop
         X := 0;
         Y := 0;
         Task1.Start;
         Task2.Start;
         
         Task1.Stop;
         Task2.Stop;
         
         Iterations := Iterations + 1;

         -- If both are 0, then at least one got reordered
         if X_Copy = 0 and Y_Copy = 0 then
            Detections := Detections + 1;
            Ada.Text_IO.Put_Line
               (Integer'Image(Detections)
                & " reorders found in "
                & Integer'Image(Iterations)
                & " iterations");
         end if;
         
      end loop;
   end Run;
end Test_Reorder;

^ permalink raw reply	[relevance 4%]

* Re: Question about sets and expression
  @ 2017-05-09  5:48  7%     ` reinert
  0 siblings, 0 replies; 200+ results
From: reinert @ 2017-05-09  5:48 UTC (permalink / raw)


Could anybody try this simple program below?

I get the output (debian, gnat-4.9):

--------------------------------------------------------------------------
** A: 
** B: 

raised PROGRAM_ERROR : test1b.adb:29 finalize/adjust raised exception
--------------------------------------------------------------------------
 Why "finalize/adjust raised exception" ?

reinert
https://korsnesbiocomputing.no/


with Ada.Numerics;
use  Ada.Numerics;
with Ada.Numerics.Generic_Real_Arrays;
with Ada.Containers.Ordered_Sets;

with Text_IO;use Text_IO;
procedure test1b is

   subtype real is Float;
   subtype degree_t is real range 0.0 .. 360.0;
   package gra is new Ada.Numerics.Generic_Real_Arrays (real);
   use gra;
   subtype real_vector2d is gra.real_vector (1 .. 2);
   type target_t is (cnil,C000,C001,C002,C003,C004);
   package cell_names_sets is new Ada.Containers.Ordered_Sets (target_t);

   type cell_state_t is
     (live,
      apoptosis,
      necrotic,
      dead,
      mitosis,
      mitotic_catastrophe,
      refusion,
      unknown,
      out_of_scene,
      ghost);

   type cell_observation_t is record
      id                  : target_t;
      state               : cell_state_t         := live;
      r, dr               : real_vector2d        := (0.0, 0.0);
      axis                : degree_t;
      children1           : cell_names_sets.set  := cell_names_sets.empty_set;
      pre_cell, next_cell : target_t             := cnil;
   end record;

   function "<"
     (left, right : cell_observation_t) return Boolean is
     (left.id < right.id);
   function "="
     (left, right : cell_observation_t) return Boolean is
     (left.id = right.id);

    package cell_observation_set is new Ada.Containers.Ordered_Sets
     (Element_Type => cell_observation_t);
    use cell_observation_set;

    os : cell_observation_set.set := to_set((id => C003,others => <>));
    c : cell_observation_t;
    d : cell_observation_t := (id => Cnil,others => <>);

begin

 Put_Line(" ** A: ");
 c := (if not os.is_empty then os.first_element else d);
 Put_Line(" ** B: ");
 c := (if not os.is_empty then os.first_element else (id => Cnil, others => <>));
 Put_Line(" ** C ");

end test1b;


^ permalink raw reply	[relevance 7%]

* Example Ada calling Gnu Scientific Library (GSL)
@ 2017-03-29  1:29  4% Leo Brewin
  0 siblings, 0 replies; 200+ results
From: Leo Brewin @ 2017-03-29  1:29 UTC (permalink / raw)


Hi Folks,

I've been following the discussion about the thin bindings to the GSL library (and thanks to all for the useful information).

I decided to follow the suggestion by Per Sandberg (Mar 19) to use gcc to create the header files. After a small amount of fiddling I got things working. And I'm very impressed with just how painless the whole process was. So here is a short summary of what I did.

1. Created a simple C-file, "integral.c"

#include <gsl/gsl_integration.h>
int main (void) {}

2. Run "gcc -fdump-ada-spec integral.c"
3. Replace "limited with" by "with" on line 6 of gsl_gsl_integration_h.ads
4. Used the generated headers to glean the required Ada syntax to create the
   thin binding needed for a simple GSL example. Here is the main program

with Ada.Text_IO;                 use Ada.Text_IO;
with Interfaces.C;                use Interfaces.C;

with gsl_gsl_math_h;
with gsl_gsl_integration_h;
with sys_utypes_usize_t_h;

with fun; -- function to integerate, must be in a separate pacakge

procedure GSL_Test is

   a,b         : Interfaces.C.double;
   epsabs      : Interfaces.C.double;
   epsrel      : Interfaces.C.double;
   abserr      : aliased Interfaces.C.double;
   result      : aliased Interfaces.C.double;
   limit       : sys_utypes_usize_t_h.size_t;
   key         : Interfaces.C.int;
   return_code : Interfaces.C.int;

   integrand   : aliased gsl_gsl_math_h.gsl_function;
   alpha       : Interfaces.C.double := 4.0;

   workspace   : access  gsl_gsl_integration_h.gsl_integration_workspace;
   size        : aliased sys_utypes_usize_t_h.size_t;
   level       : access  sys_utypes_usize_t_h.size_t;

begin

   a := 0.0;              -- lower limit
   b := 1.0;              -- upper limit

   epsabs := 1.0e-25;     -- target actual error
   epsrel := 1.0e-13;     -- target relative error, 1.0e-14 gives a GSL error
   limit  := 1000;        -- maximum number of sub-intervals
   key    := 5;           -- which integration method to use, range from 1 to 6

   integrand.c_function := fun.f'access;    -- the function to integrate
   integrand.params     := alpha'address;   -- parameters for the function

   workspace := gsl_gsl_integration_h.gsl_integration_workspace_alloc (limit);

   return_code := gsl_gsl_integration_h.gsl_integration_qag
                    (integrand'access,a,b,epsabs,epsrel,limit,key,workspace,result'access,abserr'access);

   put ("Intgeral (qag)  = ");
   put (Interfaces.C.double'Image(result));
   new_line;

   return_code := gsl_gsl_integration_h.gsl_integration_qags
                    (integrand'access,a,b,epsabs,epsrel,limit,workspace,result'access,abserr'access);

   put ("Intgeral (qags) = ");
   put (Interfaces.C.double'Image(result));
   new_line;

   size  := workspace.size;
   level := workspace.level;

   put ("Workspace size  = ");
   put (sys_utypes_usize_t_h.size_t'Image(size));
   new_line;

   put ("Workspace level = ");
   put (sys_utypes_usize_t_h.size_t'Image(level.all));
   new_line;

   gsl_gsl_integration_h.gsl_integration_workspace_free (workspace);

end GSL_Test;

5. The integrand is in a separate package, here is the spec file (fun.ads)

with Interfaces.C; use Interfaces.C;
with System;

package fun is

   function f (x : Interfaces.C.double; params : System.Address) return Interfaces.C.double;
      pragma Convention (C, f);

end fun;

6. And here is the body, fun.adb

with Ada.Numerics.Generic_Elementary_Functions;

package body fun is

   package GSL_Maths is new Ada.Numerics.Generic_Elementary_Functions (Interfaces.C.double); use GSL_Maths;

   function f (x : Interfaces.C.double; params : System.Address) return Interfaces.C.double is
      alpha : Interfaces.C.double;
      for alpha'address use params;
   begin
      return log(alpha*x) / sqrt(x);
   end f;

end fun;

7. The code can be compiled using the "-lgsl" linker option (assuming GSL has been installed
   in the standard locations. I used "homebrew" on my macOS, "brew install gsl").

8. The output from the above code was

Intgeral (qag)  = -1.22741127776022E+00
Intgeral (qags) = -1.22741127776022E+00
Workspace size  =  12
Workspace level =  11

I hope this helps (sorry for the long code listing).

But I do have a question. If I chose the target relative error (epsrel) to be 1.0e-14 the GSL code fails to meet that accuracy and the Ada code crashes with a PROGRAM_ERROR. I tried to catch this with an exception block (around the call to the gsl code) but that didn't work. The exception is raised within the GSL library -- is there any way I can catch this? The GSL documentation states that even when the code fails, it returns the best answer. So I'd rather have an answer even if it didn't meet my too stringent error request.

One further note. On experiments with the GSL Bessel library I found that the GSL code uses the case sensitive nature of C to provide different versions of the Bessel functions. This is a problem for Ada which is cases insenstive. The solution is to add some unique descriptor to selected function names in the Ada headers to avoid the ambiguities.

Cheers,
Leo

^ permalink raw reply	[relevance 4%]

* Re: Interfaces.C + generics: stack overflow
  2017-03-24 12:42  4%   ` hreba
@ 2017-03-24 20:13  0%     ` Randy Brukardt
  0 siblings, 0 replies; 200+ results
From: Randy Brukardt @ 2017-03-24 20:13 UTC (permalink / raw)


I don't see anything obviously wrong with your code (Janus/Ada can't compile 
it for various reasons, including that it doesn't yet support "in out" 
parameters on functions, so I didn't learn much from that attempt.)

What I would suggest is moving all of the actual C interface stuff out of 
the generic, making the generic part of the think binding rather than trying 
to do it all in one. That's likely to get rid of any bugs and make the code 
more portable.
The body of the generic would use type conversions (and if necessary, 
Unchecked_Conversion) to match up the formal types with the types of the 
thin binding. As I noted yesterday, that would make it a lot more portable 
to compilers that support some form of code sharing (which can't, in 
general, support C interfacing in a generic body).

Hope the above gives you some suggestions to try.

                 Randy.


"hreba" <f_hreba@yahoo.com.br> wrote in message 
news:ejkigvFlkjbU1@mid.individual.net...
> On 03/23/2017 09:03 PM, Randy Brukardt wrote:
>> I agree with Jeff, there's not enough detail here to even see if there is 
>> a
>> bug or your mistake. We need to know how/where the generic is 
>> instantiated,
>> where/how the access-to-function value is created, and probably more.
>>
> The complete code follows below. The suggestion from Jeffrey is already 
> realized. The packages are:
>  - GSL wrapper for the C library
>  - Test_Integration main program, instantiates GSL
>  - Integ_Aux defines the function to be handed over
>
>> But let me say that the rules for access-to-subprogram types are 
>> different
>> inside of generics than they are in normal packages, in order to allow 
>> for
>> the possibility of generic sharing. That ought to manifest as 
>> compile-time
>> errors and/or the raising of Program_Error, so it seems that there might 
>> be
>> a compiler bug in your code. But to find that, one needs to see the whole
>> thing, not just a little corner.
>>
>> If you really want to write portable interfacing code, you would not use 
>> any
>> generics in the raw interface. (Have the generics call non-generic 
>> interface
>> code with appropriate type conversions.) Janus/Ada doesn't allow any
>> convention C stuff in generic units, because it is incompatible with the
>> extra dope needed to implemented universal generic sharing. I'd expect
>> something similar to happen for any implementation that supports almost 
>> any
>> form of generic sharing. (If you only care about GNAT, do what ever you
>> want.)
>>
> I am not writing this program only for its result, but also as an exercise 
> in Ada programming. So I want to do it the right way. So far I know 
> basically the book from John Barnes, where this topic is not treated, so 
> thanks for your comments, I will modify my program accordingly.
>
> ---------------------------------------------------------------------------
> generic
>    type Real is digits <>;
>    type Parameters is private; -- for future use
> package GSL is
>
>    gsl_Ex: Exception;
>    error_code: Integer;    -- of the last operation
>
>    type Real_Function is access function (x: Real) return Real;
>
>    procedure Integration_QNG
>      (f: Real_Function;
>       a, b, epsabs, epsrel: Real;
>       result, abserr: out Real;
>       neval: out Natural);
>
> end GSL;
> -----------------------------------------------------------------------------
> with Interfaces.C;    use Interfaces;
>
> package body GSL is
>
>    type Void_Ptr is access all Parameters;
>    pragma Convention (C, Void_Ptr);
>
>    type GSL_Inner_Function is
>      access function (x: C.double; params: Void_Ptr) return C.double;
>    pragma Convention (C, GSL_Inner_Function);
>
>    type GSL_Function is record
>       func: GSL_Inner_Function;
>       params: Void_Ptr;
>    end record;
>
>    real_func:    Real_Function;
>
>    ---------------------------------------------------------------------
>    --    Auxiliary Subprograms
>    ---------------------------------------------------------------------
>
>    function func (x: C.double; params: Void_Ptr) return C.double;
>    pragma Convention (C, func);
>
>    function func (x: C.double; params: Void_Ptr) return C.double is
>    begin return C.double (real_func (Real(x)));
>    end func;
>
>
>    function gsl_integration_qng
>      (f: in out GSL_Function;
>       a, b, epsabs, epsrel: C.double;
>       result, abserr: out C.double;
>       neval: out C.size_t)
>      return C.int;
>    pragma Import (C, gsl_integration_qng,    "gsl_integration_qng");
>
>
>    ---------------------------------------------------------------------
>    -- Exported Subprograms
>    ---------------------------------------------------------------------
>
>    procedure Integration_QNG
>      (f: Real_Function;
>       a, b, epsabs, epsrel: Real;
>       result, abserr: out Real;
>       neval: out Natural)
>    is
>       use type C.int;
>       gslf: GSL_Function;
>       status: C.int;
>       res, ae: C.double;
>       ne: C.size_t;
>    begin
>       real_func:= f;
>       gslf.func:= func'Access;
>       gslf.params:= null;
>       status:= gsl_integration_qng    -- <-- STORAGE_ERROR occurs here
>         (gslf,
>          C.double(a), C.double(b), C.double(epsabs), C.double(epsrel),
>          res, ae, ne);
>       if status /= 0 then
>          error_code:= Integer (status);
>          raise gsl_Ex with
>    "gsl_integration_qng() returns error code " &
>    C.int'Image(status);
>       end if;
>       result:= Real(res);
>       abserr:= Real(ae);
>       neval:= Natural(ne);
>    end Integration_QNG;
>
> end GSL;
> ------------------------------------------------------------------------------
> with Ada.Text_IO;    use Ada.Text_IO;
> with GSL;
> with Integ_Aux;
>
> procedure Test_Integration
> is
>    package GSL_Test is new GSL (Integ_Aux.Real, Integer);
>    use type Integ_Aux.Real;
>    a, abserr: Integ_Aux.Real;
>    neval: Natural;
> begin
>    GSL_Test.Integration_QNG
>      (Integ_Aux.Circle'Access, 0.0, 1.0, 0.001, 0.001, a, abserr, neval);
>    Put_Line("4*int_0^1 sqrt(1-x^2) dx = " & Integ_Aux.Real'Image(4.0*a));
>    Put_Line(Natural'Image(neval) & " function evaluations, " &
>           Integ_Aux.Real'Image(abserr) & " abs. error");
> end Test_Integration;
> ------------------------------------------------------------------------------
> with Interfaces;
>
> package Integ_Aux is
>
>    type Real is new Interfaces.IEEE_Float_32;
>    function Circle (x: Real) return Real;
>
> end Integ_Aux;
> ------------------------------------------------------------------------------
> with Ada.Numerics.Generic_Elementary_Functions;
>
> package body Integ_Aux is
>
>    package Functions is new
>      Ada.Numerics.Generic_Elementary_Functions (Real);
>
>    function Circle (x: Real) return Real is
>    begin return Functions.Sqrt(abs(1.0-x*x));
>    end Circle;
>
> end Integ_Aux;
> -------------------------------------------------------------------------------
> -- 
> Frank Hrebabetzky +49 / 6355 / 989 5070
> 


^ permalink raw reply	[relevance 0%]

* Re: Interfaces.C + generics: stack overflow
  @ 2017-03-24 12:42  4%   ` hreba
  2017-03-24 20:13  0%     ` Randy Brukardt
  0 siblings, 1 reply; 200+ results
From: hreba @ 2017-03-24 12:42 UTC (permalink / raw)


On 03/23/2017 09:03 PM, Randy Brukardt wrote:
> I agree with Jeff, there's not enough detail here to even see if there is a
> bug or your mistake. We need to know how/where the generic is instantiated,
> where/how the access-to-function value is created, and probably more.
>
The complete code follows below. The suggestion from Jeffrey is already 
realized. The packages are:
  - GSL			wrapper for the C library
  - Test_Integration	main program, instantiates GSL
  - Integ_Aux		defines the function to be handed over

> But let me say that the rules for access-to-subprogram types are different
> inside of generics than they are in normal packages, in order to allow for
> the possibility of generic sharing. That ought to manifest as compile-time
> errors and/or the raising of Program_Error, so it seems that there might be
> a compiler bug in your code. But to find that, one needs to see the whole
> thing, not just a little corner.
>
> If you really want to write portable interfacing code, you would not use any
> generics in the raw interface. (Have the generics call non-generic interface
> code with appropriate type conversions.) Janus/Ada doesn't allow any
> convention C stuff in generic units, because it is incompatible with the
> extra dope needed to implemented universal generic sharing. I'd expect
> something similar to happen for any implementation that supports almost any
> form of generic sharing. (If you only care about GNAT, do what ever you
> want.)
>
I am not writing this program only for its result, but also as an 
exercise in Ada programming. So I want to do it the right way. So far I 
know basically the book from John Barnes, where this topic is not 
treated, so thanks for your comments, I will modify my program accordingly.

---------------------------------------------------------------------------
generic
    type Real is digits <>;
    type Parameters is private;	-- for future use
package GSL is

    gsl_Ex:	Exception;
    error_code:	Integer;    -- of the last operation

    type Real_Function is access function (x: Real) return Real;

    procedure Integration_QNG
      (f:			Real_Function;
       a, b, epsabs, epsrel:	Real;
       result, abserr:		out Real;
       neval:			out Natural);

end GSL;
-----------------------------------------------------------------------------
with Interfaces.C;    use Interfaces;

package body GSL is

    type Void_Ptr is access all Parameters;
    pragma Convention (C, Void_Ptr);

    type GSL_Inner_Function is
      access function (x: C.double; params: Void_Ptr) return C.double;
    pragma Convention (C, GSL_Inner_Function);

    type GSL_Function is record
       func:	GSL_Inner_Function;
       params:	Void_Ptr;
    end record;

    real_func:    Real_Function;

    ---------------------------------------------------------------------
    --    Auxiliary Subprograms
    ---------------------------------------------------------------------

    function func (x: C.double; params: Void_Ptr) return C.double;
    pragma Convention (C, func);

    function func (x: C.double; params: Void_Ptr) return C.double is
    begin return C.double (real_func (Real(x)));
    end func;


    function gsl_integration_qng
      (f:			in out GSL_Function;
       a, b, epsabs, epsrel:	C.double;
       result, abserr:		out C.double;
       neval:			out C.size_t)
      return C.int;
    pragma Import (C, gsl_integration_qng,    "gsl_integration_qng");


    ---------------------------------------------------------------------
    -- Exported Subprograms
    ---------------------------------------------------------------------

    procedure Integration_QNG
      (f:			Real_Function;
       a, b, epsabs, epsrel:	Real;
       result, abserr:		out Real;
       neval:			out Natural)
    is
       use type C.int;
       gslf:	GSL_Function;
       status:	C.int;
       res, ae:	C.double;
       ne:	C.size_t;
    begin
       real_func:= f;
       gslf.func:= func'Access;
       gslf.params:= null;
       status:= gsl_integration_qng    -- <-- STORAGE_ERROR occurs here
         (gslf,
          C.double(a), C.double(b), C.double(epsabs), C.double(epsrel),
          res, ae, ne);
       if status /= 0 then
          error_code:= Integer (status);
          raise gsl_Ex with
	   "gsl_integration_qng() returns error code " &
	   C.int'Image(status);
       end if;
       result:= Real(res);
       abserr:= Real(ae);
       neval:= Natural(ne);
    end Integration_QNG;

end GSL;
------------------------------------------------------------------------------
with Ada.Text_IO;    use Ada.Text_IO;
with GSL;
with Integ_Aux;

procedure Test_Integration
is
    package GSL_Test is new GSL (Integ_Aux.Real, Integer);
    use type Integ_Aux.Real;
    a, abserr:	Integ_Aux.Real;
    neval:	Natural;
begin
    GSL_Test.Integration_QNG
      (Integ_Aux.Circle'Access, 0.0, 1.0, 0.001, 0.001, a, abserr, neval);
    Put_Line("4*int_0^1 sqrt(1-x^2) dx = " & Integ_Aux.Real'Image(4.0*a));
    Put_Line(Natural'Image(neval) & " function evaluations, " &
           Integ_Aux.Real'Image(abserr) & " abs. error");
end Test_Integration;
------------------------------------------------------------------------------
with Interfaces;

package Integ_Aux is

    type Real is new Interfaces.IEEE_Float_32;
    function Circle (x: Real) return Real;

end Integ_Aux;
------------------------------------------------------------------------------
with Ada.Numerics.Generic_Elementary_Functions;

package body Integ_Aux is

    package Functions is new
      Ada.Numerics.Generic_Elementary_Functions (Real);

    function Circle (x: Real) return Real is
    begin return Functions.Sqrt(abs(1.0-x*x));
    end Circle;

end Integ_Aux;
-------------------------------------------------------------------------------
-- 
Frank Hrebabetzky		+49 / 6355 / 989 5070

^ permalink raw reply	[relevance 4%]

* Re: Interfaces.C questions
  2017-03-20 14:04  4%         ` hreba
@ 2017-03-22 11:21  0%           ` hreba
  0 siblings, 0 replies; 200+ results
From: hreba @ 2017-03-22 11:21 UTC (permalink / raw)


On 03/20/2017 03:04 PM, hreba wrote:
> My posting earlier was too fast: the program compiles, but terminates
> with a
> STORAGE_ERROR : stack overflow or erroneous memory access.
> This happens right at the call of gsl_integration_qng(), the function
> exported from the C library.
>
> If somebody has an idea what could be wrong ...
>
> My wrapper is package GSL:
>
> ----------------------------------------------------------------------
> generic
>    type Real is digits <>;
>    type Parameters is private;
> package GSL is
>
>    gsl_Ex:    Exception;
>    error_code:    Integer;    -- of the last operation
>
>    type Real_Function is access function (x: Real) return Real;
>
>    procedure Integration_QNG
>      (f:            Real_Function;
>       a, b, epsabs, epsrel:    Real;
>       result, abserr:        out Real;
>       neval:            out Natural);
>
> end GSL;
> -----------------------------------------------------------------------
> -----------------------------------------------------------------------
> with Interfaces.C;    use Interfaces;
>
> package body GSL is
>
>    type Void_Ptr is access all Parameters;
>    pragma Convention (C, Void_Ptr);
>
>    type GSL_Inner_Function is
>      access function (x: C.double; params: Void_Ptr) return C.double;
>    pragma Convention (C, GSL_Inner_Function);
>
>    type GSL_Function is record
>       func:    GSL_Inner_Function;
>       params:    Void_Ptr;
>    end record;
>
>    real_func:    Real_Function;
>
>    ---------------------------------------------------------------------
>    --    Auxiliary Subprograms
>    ---------------------------------------------------------------------
>
>    function func (x: C.double; params: Void_Ptr) return C.double;
>    pragma Convention (C, func);
>
>    function func (x: C.double; params: Void_Ptr) return C.double is
>    begin return C.double (real_func (Real(x)));
>    end func;
>
>
>    function gsl_integration_qng
>      (f: access GSL_Function;
>       a, b, epsabs, epsrel: C.double;
>       result, abserr: out C.double;
>       neval: out C.size_t)
>      return C.int;
>    pragma Import (C, gsl_integration_qng,    "gsl_integration_qng");
>
>
>    ---------------------------------------------------------------------
>    -- Exported Subprograms
>    ---------------------------------------------------------------------
>
>    procedure Integration_QNG
>      (f: Real_Function;
>       a, b, epsabs, epsrel:    Real;
>       result, abserr:        out Real;
>       neval:            out Natural)
>    is
>       use type C.int;
>       gslf:    aliased GSL_Function;
>       status:    C.int;
>       res, ae:    C.double;
>       ne:    C.size_t;
>    begin
>       real_func:= f;
>       gslf.func:= func'Access;
>       gslf.params:= null;
>       status:= gsl_integration_qng    -- <-- STORAGE_ERROR occurs here
>     (gslf'Access,
>      C.double(a), C.double(b), C.double(epsabs), C.double(epsrel),
>      res, ae, ne);
>       if status /= 0 then
>      error_code:= Integer (status);
>      raise gsl_Ex with
>        "gsl_integration_qng() returns error code " & C.int'Image(status);
>       end if;
>       result:= Real(res);
>       abserr:= Real(ae);
>       neval:= Natural(ne);
>    end Integration_QNG;
>
> end GSL;
> -------------------------------------------------------------------------
>
> The test application is
>
> -------------------------------------------------------------------------
> with Ada.Text_IO;    use Ada.Text_IO;
> with GSL;
> with Integ_Aux;
>
> procedure Test_Integration
> is
>    package GSL_Test is new GSL (Integ_Aux.Real, Integer);
>    use type Integ_Aux.Real;
>    a, abserr:    Integ_Aux.Real;
>    neval:    Natural;
> begin
>    GSL_Test.Integration_QNG
>      (Integ_Aux.Circle'Access, 0.0, 1.0, 0.001, 0.001, a, abserr, neval);
>    Put_Line("4*int_0^1 sqrt(1-x^2) dx = " & Integ_Aux.Real'Image(4.0*a));
>    Put_Line(Natural'Image(neval) & " function evaluations, " &
>           Integ_Aux.Real'Image(abserr) & " abs. error");
> end Test_Integration;
> ---------------------------------------------------------------------------
>
> which imports also
>
> ---------------------------------------------------------------------------
> with Interfaces;
>
> package Integ_Aux is
>
>    type Real is new Interfaces.IEEE_Float_32;
>    function Circle (x: Real) return Real;
>
> end Integ_Aux;
> ---------------------------------------------------------------------------
> ---------------------------------------------------------------------------
> with Ada.Numerics.Generic_Elementary_Functions;
>
> package body Integ_Aux is
>
>    package Functions is new
>      Ada.Numerics.Generic_Elementary_Functions (Real);
>
>    function Circle (x: Real) return Real is
>    begin return Functions.Sqrt(abs(1.0-x*x));
>    end Circle;
>
> end Integ_Aux;
> ------------------------------------------------------------------------------
>
>
I experimented a little. When I delete the formal type parameter "Real" 
from the "generic" specification of package GSL, and declare a subtype 
"Real" inside it, then it works as expected.

I wrote a simpler example too, where just a function (gsl_bessl_j0) is 
called from the C library, and no function reference is passed as a 
parameter. This worked in the non-generic as well in the generic version.

If somebody could have a look ...

-- 
Frank Hrebabetzky		+49 / 6355 / 989 5070

^ permalink raw reply	[relevance 0%]

* Re: Interfaces.C questions
  @ 2017-03-20 14:04  4%         ` hreba
  2017-03-22 11:21  0%           ` hreba
  0 siblings, 1 reply; 200+ results
From: hreba @ 2017-03-20 14:04 UTC (permalink / raw)


My posting earlier was too fast: the program compiles, but terminates with a
STORAGE_ERROR : stack overflow or erroneous memory access.
This happens right at the call of gsl_integration_qng(), the function 
exported from the C library.

If somebody has an idea what could be wrong ...

My wrapper is package GSL:

----------------------------------------------------------------------
generic
    type Real is digits <>;
    type Parameters is private;
package GSL is

    gsl_Ex:	Exception;
    error_code:	Integer;	-- of the last operation

    type Real_Function is access function (x: Real) return Real;

    procedure Integration_QNG
      (f:			Real_Function;
       a, b, epsabs, epsrel:	Real;
       result, abserr:		out Real;
       neval:			out Natural);

end GSL;
-----------------------------------------------------------------------
-----------------------------------------------------------------------
with Interfaces.C;	use Interfaces;

package body GSL is

    type Void_Ptr is access all Parameters;
    pragma Convention (C, Void_Ptr);

    type GSL_Inner_Function is
      access function (x: C.double; params: Void_Ptr) return C.double;
    pragma Convention (C, GSL_Inner_Function);

    type GSL_Function is record
       func:	GSL_Inner_Function;
       params:	Void_Ptr;
    end record;

    real_func:	Real_Function;

    ---------------------------------------------------------------------
    --	Auxiliary Subprograms
    ---------------------------------------------------------------------

    function func (x: C.double; params: Void_Ptr) return C.double;
    pragma Convention (C, func);

    function func (x: C.double; params: Void_Ptr) return C.double is
    begin return C.double (real_func (Real(x)));
    end func;


    function gsl_integration_qng
      (f: access GSL_Function;
       a, b, epsabs, epsrel: C.double;
       result, abserr: out C.double;
       neval: out C.size_t)
      return C.int;
    pragma Import (C, gsl_integration_qng,	"gsl_integration_qng");


    ---------------------------------------------------------------------
    -- Exported Subprograms
    ---------------------------------------------------------------------

    procedure Integration_QNG
      (f: Real_Function;
       a, b, epsabs, epsrel:	Real;
       result, abserr:		out Real;
       neval:			out Natural)
    is
       use type C.int;
       gslf:	aliased GSL_Function;
       status:	C.int;
       res, ae:	C.double;
       ne:	C.size_t;
    begin
       real_func:= f;
       gslf.func:= func'Access;
       gslf.params:= null;
       status:= gsl_integration_qng    -- <-- STORAGE_ERROR occurs here
	(gslf'Access,
	 C.double(a), C.double(b), C.double(epsabs), C.double(epsrel),
	 res, ae, ne);
       if status /= 0 then
	 error_code:= Integer (status);
	 raise gsl_Ex with
	   "gsl_integration_qng() returns error code " & C.int'Image(status);
       end if;
       result:= Real(res);
       abserr:= Real(ae);
       neval:= Natural(ne);
    end Integration_QNG;

end GSL;
-------------------------------------------------------------------------

The test application is

-------------------------------------------------------------------------
with Ada.Text_IO;	use Ada.Text_IO;
with GSL;
with Integ_Aux;

procedure Test_Integration
is
    package GSL_Test is new GSL (Integ_Aux.Real, Integer);
    use type Integ_Aux.Real;
    a, abserr:	Integ_Aux.Real;
    neval:	Natural;
begin
    GSL_Test.Integration_QNG
      (Integ_Aux.Circle'Access, 0.0, 1.0, 0.001, 0.001, a, abserr, neval);
    Put_Line("4*int_0^1 sqrt(1-x^2) dx = " & Integ_Aux.Real'Image(4.0*a));
    Put_Line(Natural'Image(neval) & " function evaluations, " &
	      Integ_Aux.Real'Image(abserr) & " abs. error");
end Test_Integration;
---------------------------------------------------------------------------

which imports also

---------------------------------------------------------------------------
with Interfaces;

package Integ_Aux is

    type Real is new Interfaces.IEEE_Float_32;
    function Circle (x: Real) return Real;

end Integ_Aux;
---------------------------------------------------------------------------
---------------------------------------------------------------------------
with Ada.Numerics.Generic_Elementary_Functions;

package body Integ_Aux is

    package Functions is new
      Ada.Numerics.Generic_Elementary_Functions (Real);

    function Circle (x: Real) return Real is
    begin return Functions.Sqrt(abs(1.0-x*x));
    end Circle;

end Integ_Aux;
------------------------------------------------------------------------------

-- 
Frank Hrebabetzky		+49 / 6355 / 989 5070


^ permalink raw reply	[relevance 4%]

* Re: Interfaces.C questions
  2017-03-19 12:17  4%   ` hreba
@ 2017-03-20  9:44  0%     ` Leo Brewin
  0 siblings, 0 replies; 200+ results
From: Leo Brewin @ 2017-03-20  9:44 UTC (permalink / raw)


Hi Frank,

Many thanks for sharing that code. I've wanted to play with GSL for a while but couldn't make sense of the C parameters and how to connect them back to Ada. Thanks again.

Cheers,
Leo

On Sunday, March 19, 2017 at 11:17:37 PM UTC+11, hreba wrote:
> On 03/19/2017 12:24 AM, Leo Brewin wrote:
> > Hi Frank,
> >
> > I'd be really interested to see a minimal working example once you've got it running.
> > I'd like to be able to use GSL in my own codes.
> >
> > Cheers,
> > Leo
> >
> 
> Ok, below follows my first working example, numerical quadrature. Any 
> critics is welcome. Some remarks:
> 
> 'void * params' in C can be a pointer to just anything, a number, an 
> array, a record. The best solution probably would be  a generic package 
> where the actual type is passed as parameter (see type Element in 
> Interfaces.C.Pointers). The quadrature algorithm I chose makes no use of 
> these parameters, so in my example I translate the type to 'access all 
> Integer' and pass null as value.
> 
> As I am beginning to build a numerics library, I will now
> 
>   - make the package generic, with 2 type parameters, one for the reals
>     (digits <>) and one for the parameters (private),
>   - write wrappers so that the client needs no Interfaces.C, and that he
>     can pass a function of
>     'type Real_Function is access function (x: Real) return Real;'
>     to the quadrature procedure instead of a record.
> 
> So here comes my example. The interface package is (no body):
> 
> -----------------------------------------------------------------------
> with Interfaces.C;
> 
> package GSL is
> 
>     package C renames Interfaces.C;
> 
>     type Void_Ptr is access all Integer;
>     type GSL_Function_Ptr is access
>       function (x: C.double; params: Void_Ptr) return C.double;
>     type GSL_Function is record
>        func:	GSL_Function_Ptr;
>        params:	Void_Ptr;
>     end record;
> 
> 
>     function Integration_QNG
>       (f: access GSL_Function;
>        a, b, epsabs, epsrel: C.double;
>        result, abserr: out C.double;
>        neval: out C.size_t)
>       return C.int;
> 
> private
> 
>     pragma Import (C, Integration_QNG, "gsl_integration_qng");
>     pragma Convention (C, Void_Ptr);
>     pragma Convention (C, GSL_Function_Ptr);
>     pragma Convention (C, GSL_Function);
> 
> end GSL;
> -----------------------------------------------------------------------------
> 
> The main subprogram (client) is
> 
> -----------------------------------------------------------------------------
> with Ada.Text_IO;	use Ada.Text_IO;
> with GSL;
> with Integ_Aux;
> 
> procedure Test_Integration
> is
>     use type GSL.C.double;
>     a:		GSL.C.double;
>     abserr:	GSL.C.double;
>     neval:	GSL.C.size_t;
>     res:		GSL.C.int;
>     gslf:	aliased GSL.GSL_Function;
> 
> begin
>     gslf.func:= Integ_Aux.Circle'Access;
>     gslf.params:= null;
>     res:= GSL.Integration_QNG
>       (gslf'Access, 0.0, 1.0, 0.001, 0.001, a, abserr, neval);
>     Put_Line("4*int_0^1 sqrt(1-x^2) dx = " & GSL.C.double'Image(4.0*a));
>     Put_Line(GSL.C.size_t'Image(neval) & " function evaluations, " &
> 	      GSL.C.double'Image(abserr) & " abs. error");
> end Test_Integration;
> ------------------------------------------------------------------------------
> Because an access is passed to the function to be integrated it has to 
> be in a separated package:
> ------------------------------------------------------------------------------
> with GSL;
> 
> package Integ_Aux is
>        function Circle (x: GSL.C.double; pars: GSL.Void_Ptr) return 
> GSL.C.double;
> 
> private
>     pragma Convention (C, Circle);
> end Integ_Aux;
> -------------------------------------------------------------------------------
> -------------------------------------------------------------------------------
> with Ada.Numerics.Generic_Elementary_Functions;
> with GSL;
> 
> package body Integ_Aux is
> 
>     package Functions is new
>       Ada.Numerics.Generic_Elementary_Functions (GSL.C.double);
> 
>     function Circle (x: GSL.C.double; pars: GSL.Void_Ptr) return 
> GSL.C.double is
>     use type GSL.C.double;
>     begin return Functions.Sqrt(abs(1.0-x*x));
>     end Circle;
> 
> end Integ_Aux;
> --------------------------------------------------------------------------------
> The project files of the interface package are
> --------------------------------------------------------------------------------
> -- External library "Gnu Scientific Library"
> 
> with "gslcblas";
> 
> Project GSL is
> 
>     type OS_Type is ("linux", "linux-gnu", "windows", "unknown");
>     act_os: OS_Type:= external ("OSTYPE");
>     -- act_os: OS_Type:= external ("OS_TYPE");
> 
>     For externally_built use "true";
>     For library_dir use "/usr/lib";
>     case act_os is
>        when "linux"|"linux-gnu" => for library_dir use "/usr/lib";
>        when "windows" => for library_dir use "/Lib/GSL";
>        when "unknown" => for Source_Dirs use ("/");	-- just anything
>     end case;
>     For library_name use "gsl";
>     For source_dirs use (); -- no sources.
>     -- For library_kind use "static";
>     -- if it is a static lib .a
> 
>     for library_kind use "dynamic";
>     -- if it is an so.
> 
> end GSL;
> -------------------------------------------------------------------------
> -------------------------------------------------------------------------
> -- External library "Gnu Scientific Library"
> 
> 
> Project GSLCBLAS is
> 
>     type OS_Type is ("linux", "linux-gnu", "windows", "unknown");
>     act_os: OS_Type:= external ("OSTYPE");
>     -- act_os: OS_Type:= external ("OS_TYPE");
> 
>     For externally_built use "true";
>     case act_os is
>        when "linux"|"linux-gnu" => for library_dir use "/usr/lib";
>        when "windows" => for library_dir use "/Lib/GSL";
>        when "unknown" => for Source_Dirs use ("/");	-- just anything
>     end case;
>     For library_name use "gslcblas";
>     For source_dirs use (); -- no sources.
>     -- For library_kind use "static";
>     -- if it is a static lib .a
> 
>     for library_kind use "dynamic";
>     -- if it is an so.
> 
> end GSLCBLAS;
> -----------------------------------------------------------------------------
> I tried to make these projects platform independent (Linux and Windows 
> so far); only tested on Linux so far. The environment variable OSTYPE 
> must exist. If you don't want to do this, just type
> for library_dir use "/usr/lib";
> instead of the 'case' construct (on Linux).
> Finally the project file for the main program:
> -----------------------------------------------------------------------------
> with "../../gsl.gpr";
> 
> project Test_Integration is
> 
>     for Source_Dirs use (".", "../../src"); -- test and interface sources
>     for Object_Dir use "../obj";
>     for Exec_Dir use ".";
>     for Main use ("test_integration.adb");
> 
>     package Compiler is
>        for Default_Switches ("ada") use ("-g", "-gnatf", "-gnat2012");
>     end Compiler;
> 
>     package Linker is
>        for Default_Switches ("ada") use ("-g");
>     end Linker;
> 
>     package Builder is
>        for Default_Switches ("ada") use ("-g");
>     end Builder;
> 
> end Test_Integration;
> ------------------------------------------------------------------------------
> The result is an approximation of the unit circle area, pi.
> 
> -- 
> Frank Hrebabetzky		+49 / 6355 / 989 5070

^ permalink raw reply	[relevance 0%]

* Re: Interfaces.C questions
  @ 2017-03-19 12:17  4%   ` hreba
  2017-03-20  9:44  0%     ` Leo Brewin
  0 siblings, 1 reply; 200+ results
From: hreba @ 2017-03-19 12:17 UTC (permalink / raw)


On 03/19/2017 12:24 AM, Leo Brewin wrote:
> Hi Frank,
>
> I'd be really interested to see a minimal working example once you've got it running.
> I'd like to be able to use GSL in my own codes.
>
> Cheers,
> Leo
>

Ok, below follows my first working example, numerical quadrature. Any 
critics is welcome. Some remarks:

'void * params' in C can be a pointer to just anything, a number, an 
array, a record. The best solution probably would be  a generic package 
where the actual type is passed as parameter (see type Element in 
Interfaces.C.Pointers). The quadrature algorithm I chose makes no use of 
these parameters, so in my example I translate the type to 'access all 
Integer' and pass null as value.

As I am beginning to build a numerics library, I will now

  - make the package generic, with 2 type parameters, one for the reals
    (digits <>) and one for the parameters (private),
  - write wrappers so that the client needs no Interfaces.C, and that he
    can pass a function of
    'type Real_Function is access function (x: Real) return Real;'
    to the quadrature procedure instead of a record.

So here comes my example. The interface package is (no body):

-----------------------------------------------------------------------
with Interfaces.C;

package GSL is

    package C renames Interfaces.C;

    type Void_Ptr is access all Integer;
    type GSL_Function_Ptr is access
      function (x: C.double; params: Void_Ptr) return C.double;
    type GSL_Function is record
       func:	GSL_Function_Ptr;
       params:	Void_Ptr;
    end record;


    function Integration_QNG
      (f: access GSL_Function;
       a, b, epsabs, epsrel: C.double;
       result, abserr: out C.double;
       neval: out C.size_t)
      return C.int;

private

    pragma Import (C, Integration_QNG, "gsl_integration_qng");
    pragma Convention (C, Void_Ptr);
    pragma Convention (C, GSL_Function_Ptr);
    pragma Convention (C, GSL_Function);

end GSL;
-----------------------------------------------------------------------------

The main subprogram (client) is

-----------------------------------------------------------------------------
with Ada.Text_IO;	use Ada.Text_IO;
with GSL;
with Integ_Aux;

procedure Test_Integration
is
    use type GSL.C.double;
    a:		GSL.C.double;
    abserr:	GSL.C.double;
    neval:	GSL.C.size_t;
    res:		GSL.C.int;
    gslf:	aliased GSL.GSL_Function;

begin
    gslf.func:= Integ_Aux.Circle'Access;
    gslf.params:= null;
    res:= GSL.Integration_QNG
      (gslf'Access, 0.0, 1.0, 0.001, 0.001, a, abserr, neval);
    Put_Line("4*int_0^1 sqrt(1-x^2) dx = " & GSL.C.double'Image(4.0*a));
    Put_Line(GSL.C.size_t'Image(neval) & " function evaluations, " &
	      GSL.C.double'Image(abserr) & " abs. error");
end Test_Integration;
------------------------------------------------------------------------------
Because an access is passed to the function to be integrated it has to 
be in a separated package:
------------------------------------------------------------------------------
with GSL;

package Integ_Aux is
       function Circle (x: GSL.C.double; pars: GSL.Void_Ptr) return 
GSL.C.double;

private
    pragma Convention (C, Circle);
end Integ_Aux;
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
with Ada.Numerics.Generic_Elementary_Functions;
with GSL;

package body Integ_Aux is

    package Functions is new
      Ada.Numerics.Generic_Elementary_Functions (GSL.C.double);

    function Circle (x: GSL.C.double; pars: GSL.Void_Ptr) return 
GSL.C.double is
    use type GSL.C.double;
    begin return Functions.Sqrt(abs(1.0-x*x));
    end Circle;

end Integ_Aux;
--------------------------------------------------------------------------------
The project files of the interface package are
--------------------------------------------------------------------------------
-- External library "Gnu Scientific Library"

with "gslcblas";

Project GSL is

    type OS_Type is ("linux", "linux-gnu", "windows", "unknown");
    act_os: OS_Type:= external ("OSTYPE");
    -- act_os: OS_Type:= external ("OS_TYPE");

    For externally_built use "true";
    For library_dir use "/usr/lib";
    case act_os is
       when "linux"|"linux-gnu" => for library_dir use "/usr/lib";
       when "windows" => for library_dir use "/Lib/GSL";
       when "unknown" => for Source_Dirs use ("/");	-- just anything
    end case;
    For library_name use "gsl";
    For source_dirs use (); -- no sources.
    -- For library_kind use "static";
    -- if it is a static lib .a

    for library_kind use "dynamic";
    -- if it is an so.

end GSL;
-------------------------------------------------------------------------
-------------------------------------------------------------------------
-- External library "Gnu Scientific Library"


Project GSLCBLAS is

    type OS_Type is ("linux", "linux-gnu", "windows", "unknown");
    act_os: OS_Type:= external ("OSTYPE");
    -- act_os: OS_Type:= external ("OS_TYPE");

    For externally_built use "true";
    case act_os is
       when "linux"|"linux-gnu" => for library_dir use "/usr/lib";
       when "windows" => for library_dir use "/Lib/GSL";
       when "unknown" => for Source_Dirs use ("/");	-- just anything
    end case;
    For library_name use "gslcblas";
    For source_dirs use (); -- no sources.
    -- For library_kind use "static";
    -- if it is a static lib .a

    for library_kind use "dynamic";
    -- if it is an so.

end GSLCBLAS;
-----------------------------------------------------------------------------
I tried to make these projects platform independent (Linux and Windows 
so far); only tested on Linux so far. The environment variable OSTYPE 
must exist. If you don't want to do this, just type
for library_dir use "/usr/lib";
instead of the 'case' construct (on Linux).
Finally the project file for the main program:
-----------------------------------------------------------------------------
with "../../gsl.gpr";

project Test_Integration is

    for Source_Dirs use (".", "../../src"); -- test and interface sources
    for Object_Dir use "../obj";
    for Exec_Dir use ".";
    for Main use ("test_integration.adb");

    package Compiler is
       for Default_Switches ("ada") use ("-g", "-gnatf", "-gnat2012");
    end Compiler;

    package Linker is
       for Default_Switches ("ada") use ("-g");
    end Linker;

    package Builder is
       for Default_Switches ("ada") use ("-g");
    end Builder;

end Test_Integration;
------------------------------------------------------------------------------
The result is an approximation of the unit circle area, pi.

-- 
Frank Hrebabetzky		+49 / 6355 / 989 5070


^ permalink raw reply	[relevance 4%]

* Re: Ada.Numerics.Long_Real_Arrays
  2017-01-27 16:51 11% ` Ada.Numerics.Long_Real_Arrays hnptz
@ 2017-01-27 18:39 13%   ` Simon Wright
  0 siblings, 0 replies; 200+ results
From: Simon Wright @ 2017-01-27 18:39 UTC (permalink / raw)


hnptz@yahoo.de writes:

> with Ada.Text_Io; use Ada.Text_Io; 
> with Nm_G; 
> procedure Nm_Test is 
>    package Nm is new Nm_G (Rows => 3); 
>    use Nm; 
>    P : R_Matrix := ((42.0, 42.0), (43.0, 43.0), (44.0, 44.0)); 
>    V,X  : R_Vector := P (P'Last);
>    MLF : Long_Float := 6.0; 
> begin 
>    Put_Line ("v: " & V (V'First)'Img & ", " & V (V'Last)'Img); 
>    X := V / MLF;
>    Put_Line ("X: " & X (X'First)'Img & ", " & X(X'Last)'Img); 
> end Nm_Test; 
>
> It should also work according to the description in the ARM 2012.
> However, it says: expected type "Standard.Long_Float"

This is because I declared Nm_G.R_Vector as a subtype; the required
operation "/" of Ada.Numerics.Long_Real_Arrays.Real_Vector isn't
visible.

You could modify your Nm_Test to

   use type Ada.Numerics.Long_Real_Arrays.Real_Vector;

but the best approach (I think): declare Nm_G.R_Vector as a type,

   type R_Vector
   is new Ada.Numerics.Long_Real_Arrays.Real_Vector (1 .. Np);

^ permalink raw reply	[relevance 13%]

* Re: Ada.Numerics.Long_Real_Arrays
  2017-01-25 12:25 12% Ada.Numerics.Long_Real_Arrays hnptz
                   ` (3 preceding siblings ...)
  2017-01-25 21:29  5% ` Ada.Numerics.Long_Real_Arrays hnptz
@ 2017-01-27 16:51 11% ` hnptz
  2017-01-27 18:39 13%   ` Ada.Numerics.Long_Real_Arrays Simon Wright
  4 siblings, 1 reply; 200+ results
From: hnptz @ 2017-01-27 16:51 UTC (permalink / raw)


> Hi,
> 
> these are my definitions:
> 
> with Ada.Numerics.Long_Real_Arrays; use Ada.Numerics.Long_Real_Arrays;
> package nm is
> 
> Np : Positive;
> Type R_Vector is new Real_Vector (1..Np);
> Type R_Matrix is array (Positive range <>) of R_Vector;
> 
> procedure nm1 (P : in out R_Matrix);
> 
> end nm;
> 
> -- definition of procedure nm1 in package body nm done.
> 
> now in procedure test_nm.adb (only definitions):
> 
> Np : Positive := 2;
> Mp : Positive := Np+1;
> 
> 24  P : R_Matrix(1..Mp) := ((x,x),(y,y),(z,z));
> 
> no "build all" error or warning
> 
> result when running:
> 
> raised CONSTRAINT_ERROR : test_nm.adb: 24 length check failed.
> 
> Can you help?


On January 25. Simon Wright wrote:

You could try a generic? 

with Ada.Numerics.Long_Real_Arrays; 
generic 
   Rows : Positive; 
package Nm_G is 
   subtype R_Vector 
     is Ada.Numerics.Long_Real_Arrays.Real_Vector (1 .. Rows - 1); 
   type R_Matrix is array (1 .. Rows) of R_Vector; 
end Nm_G; 

with Ada.Text_Io; use Ada.Text_Io; 
with Nm_G; 
procedure Nm_Test is 
   package Nm is new Nm_G (Rows => 3); 
   use Nm; 
   P : R_Matrix := ((42.0, 42.0), (43.0, 43.0), (44.0, 44.0)); 
   V : R_Vector := P (P'Last); 
begin 
   Put_Line ("v: " & V (V'First)'Img & ", " & V (V'Last)'Img); 
end Nm_Test; 

It works.

My new Nm_Test is

with Ada.Text_Io; use Ada.Text_Io; 
with Nm_G; 
procedure Nm_Test is 
   package Nm is new Nm_G (Rows => 3); 
   use Nm; 
   P : R_Matrix := ((42.0, 42.0), (43.0, 43.0), (44.0, 44.0)); 
   V,X  : R_Vector := P (P'Last);
   MLF : Long_Float := 6.0; 
begin 
   Put_Line ("v: " & V (V'First)'Img & ", " & V (V'Last)'Img); 
   X := V / MLF;
   Put_Line ("X: " & X (X'First)'Img & ", " & X(X'Last)'Img); 
end Nm_Test; 

It should also work according to the description in the ARM 2012.
However, it says: expected type "Standard.Long_Float"

Maybe it lacks implementation ?


^ permalink raw reply	[relevance 11%]

* Re: Ada.Numerics.Long_Real_Arrays
  2017-01-26 14:52 10%       ` Ada.Numerics.Long_Real_Arrays Simon Wright
@ 2017-01-26 15:03 13%         ` Simon Wright
  0 siblings, 0 replies; 200+ results
From: Simon Wright @ 2017-01-26 15:03 UTC (permalink / raw)


Simon Wright <simon@pushface.org> writes:

> I'm not sure whether one could get something less clumsy by using
> Ada.Containers.Indefinite_Vectors to hold the R_Vectors.

with Ada.Containers.Indefinite_Vectors;
with Ada.Numerics.Long_Real_Arrays;
package Nmc is
   package Matrices is new Ada.Containers.Indefinite_Vectors
     (Positive,
      Ada.Numerics.Long_Real_Arrays.Real_Vector,
      "=" => Ada.Numerics.Long_Real_Arrays."=");
   subtype Matrix is Matrices.Vector;
end Nmc;

with Nmc;
procedure Test_Nmc is
   M : Nmc.Matrix;
begin
   M (1) := (1.0, 2.0);
   M (2) := (3.0, 4.0);
   M (3) := (5.0, 6.0);
end Test_Nmc;


^ permalink raw reply	[relevance 13%]

* Re: Ada.Numerics.Long_Real_Arrays
  2017-01-26 11:54 12%     ` Ada.Numerics.Long_Real_Arrays hnptz
@ 2017-01-26 14:52 10%       ` Simon Wright
  2017-01-26 15:03 13%         ` Ada.Numerics.Long_Real_Arrays Simon Wright
  0 siblings, 1 reply; 200+ results
From: Simon Wright @ 2017-01-26 14:52 UTC (permalink / raw)


This will compile, and preserve visibility of the underlying Vectors.
I'm not sure whether one could get something less clumsy by using
Ada.Containers.Indefinite_Vectors to hold the R_Vectors.

with Ada.Numerics.Long_Real_Arrays;
generic
   Np : Positive;
package Nm_G is
   subtype R_Vector
     is Ada.Numerics.Long_Real_Arrays.Real_Vector (1 .. Np);
   type R_Matrix is array (1 .. Np + 1) of R_Vector;
end Nm_G;

with Nm_G;
package Nm is
   --  I assume there's more than just Fnm here; if not, Fnm could be a
   --  library-level generic subprogram.
   --
   --  Of course, if there _is_ more than just Fnm, it's likely the
   --  other components will also need to know which instantiation of
   --  Nm_G they have to deal with, and the 'with package' bit would
   --  need to be placed on the Nm (which itself has to be generic).
   generic
      --  This generic needs to know which instantiation of Nm_G it is
      --  to deal with.
      with package Nm_I is new Nm_G (<>);
      --  Now we know what type the parameter of the actual F has to
      --  be.
      with function F (R : Nm_I.R_Vector) return Long_Float;
   procedure Fnm (P : in out Nm_I.R_Matrix);
end Nm;

package body Nm is
   procedure Fnm (P : in out Nm_I.R_Matrix) is
   begin
      null;
   end Fnm;
end Nm;

with Nm;
with Nm_G;
procedure Test_Nm is
   package Nm_Inst is new Nm_G (Np => 2);
   function Actual_F (R : Nm_Inst.R_Vector) return Long_Float is (42.0);
   procedure Actual_Fnm is new Nm.Fnm (Nm_I => Nm_Inst,
                                       F    => Actual_F);
   P : Nm_Inst.R_Matrix := ((1.0, 2.0), (3.0, 4.0), (5.0, 6.0));
begin
   Actual_Fnm (P);
end Test_Nm;

^ permalink raw reply	[relevance 10%]

* Re: Ada.Numerics.Long_Real_Arrays
  2017-01-26  7:47  6%   ` Ada.Numerics.Long_Real_Arrays Simon Wright
@ 2017-01-26 11:54 12%     ` hnptz
  2017-01-26 14:52 10%       ` Ada.Numerics.Long_Real_Arrays Simon Wright
  0 siblings, 1 reply; 200+ results
From: hnptz @ 2017-01-26 11:54 UTC (permalink / raw)


On Thursday, January 26, 2017 at 8:47:07 AM UTC+1, Simon Wright wrote:
> hnptz@yahoo.de writes:
> 
> > I have nm_G.ads, nm.ads, nm.adb and test_nm.adb, and I want to specify
> > Np in test_nm.adb only, How can it be made possible ?
> 
> The thing is, you've supplied code examples that wouldn't even begin to
> compile because you've cut out so much and replaced with
> english-language text. The result is that we have no real idea what
> you're talking about.

I have conducted four files:

1. file nm_g.ads:

with Ada.Numerics.Long_Real_Arrays; 
generic 
  Np : Positive; 
package Nm_G is 
   subtype R_Vector 
     is Ada.Numerics.Long_Real_Arrays.Real_Vector (1 .. Np); 
   type R_Matrix is array (1 ..Np+1) of R_Vector; 
end Nm_G; 

2. file nm.ads:

with Ada.Numerics.Long_Real_Arrays; use Ada.Numerics.Long_Real_Arrays;
with nm_g;
package nm is
…
generic
with function f(R : R_Vector) return Long_Float;
procedure fnm ( P : in out R_Matrix);
…
end nm;

result: R_Matrix is not visible. But I don’t know Np at this moment.

3. file nm.adb:

package body nm is
…
procedure fnm ( P : in out R_Matrix) is
…
end fnm;
end nm;

result: R_Matrix is not visible. But I still don’t know Nt at this moment.

4. file test_nm.adb

with nm; use nm;
procedure test_nm is
Np : Positive := 2;
P : R_Matrix := ((1.0,2.0),(3.0,4.0),(5.0,6.0));
begin
fnm(P);
end test_nm;

result: cannot work

I admit this is only the way, I would like to set up the project. However, using an array of Real_Vectors may require a different approach.


^ permalink raw reply	[relevance 12%]

* Re: Ada.Numerics.Long_Real_Arrays
  2017-01-26  7:49  6%   ` Ada.Numerics.Long_Real_Arrays Simon Wright
@ 2017-01-26  7:55  6%     ` Simon Wright
  0 siblings, 0 replies; 200+ results
From: Simon Wright @ 2017-01-26  7:55 UTC (permalink / raw)


Simon Wright <simon.john.wright@gmail.com> writes:

> That way we can see how the thread fits together.

At least, those of us who use newsreaders capable of showing a threaded
view! (does anyone know how to get Google Groups to show a tree view of
threads?)

^ permalink raw reply	[relevance 6%]

* Re: Ada.Numerics.Long_Real_Arrays
  2017-01-25 21:29  5% ` Ada.Numerics.Long_Real_Arrays hnptz
  2017-01-26  7:47  6%   ` Ada.Numerics.Long_Real_Arrays Simon Wright
@ 2017-01-26  7:49  6%   ` Simon Wright
  2017-01-26  7:55  6%     ` Ada.Numerics.Long_Real_Arrays Simon Wright
  1 sibling, 1 reply; 200+ results
From: Simon Wright @ 2017-01-26  7:49 UTC (permalink / raw)


Also, it would help if you could "reply" to the immediate message rather
than to your original head message (use the leftward-curving arrow at the
top right of the immediate message). That way we can see how the thread
fits together.


^ permalink raw reply	[relevance 6%]

* Re: Ada.Numerics.Long_Real_Arrays
  2017-01-25 21:29  5% ` Ada.Numerics.Long_Real_Arrays hnptz
@ 2017-01-26  7:47  6%   ` Simon Wright
  2017-01-26 11:54 12%     ` Ada.Numerics.Long_Real_Arrays hnptz
  2017-01-26  7:49  6%   ` Ada.Numerics.Long_Real_Arrays Simon Wright
  1 sibling, 1 reply; 200+ results
From: Simon Wright @ 2017-01-26  7:47 UTC (permalink / raw)


hnptz@yahoo.de writes:

> I have nm_G.ads, nm.ads, nm.adb and test_nm.adb, and I want to specify
> Np in test_nm.adb only, How can it be made possible ?

The thing is, you've supplied code examples that wouldn't even begin to
compile because you've cut out so much and replaced with
english-language text. The result is that we have no real idea what
you're talking about.

^ permalink raw reply	[relevance 6%]

* Re: Ada.Numerics.Long_Real_Arrays
  2017-01-25 12:25 12% Ada.Numerics.Long_Real_Arrays hnptz
                   ` (2 preceding siblings ...)
  2017-01-25 18:35  6% ` Ada.Numerics.Long_Real_Arrays hnptz
@ 2017-01-25 21:29  5% ` hnptz
  2017-01-26  7:47  6%   ` Ada.Numerics.Long_Real_Arrays Simon Wright
  2017-01-26  7:49  6%   ` Ada.Numerics.Long_Real_Arrays Simon Wright
  2017-01-27 16:51 11% ` Ada.Numerics.Long_Real_Arrays hnptz
  4 siblings, 2 replies; 200+ results
From: hnptz @ 2017-01-25 21:29 UTC (permalink / raw)


On Wednesday, January 25, 2017 at 1:25:18 PM UTC+1, hn...@yahoo.de wrote:
> Hi,
> 
> these are my definitions:
> 
> with Ada.Numerics.Long_Real_Arrays; use Ada.Numerics.Long_Real_Arrays;
> package nm is
> 
> Np : Positive;
> Type R_Vector is new Real_Vector (1..Np);
> Type R_Matrix is array (Positive range <>) of R_Vector;
> 
> procedure nm1 (P : in out R_Matrix);
> 
> end nm;
> 
> -- definition of procedure nm1 in package body nm done.
> 
> now in procedure test_nm.adb (only definitions):
> 
> Np : Positive := 2;
> Mp : Positive := Np+1;
> 
> 24  P : R_Matrix(1..Mp) := ((x,x),(y,y),(z,z));
> 
> no "build all" error or warning
> 
> result when running:
> 
> raised CONSTRAINT_ERROR : test_nm.adb: 24 length check failed.
> 
> Can you help?

I have conducted the following:

nm_G.ads -- generic package as suggested -- value of Np not known

nm.ads  with nm_g
package nm is -- Np still not known
...
generic
with function f(R : R_Vector) return Long_Float;
procedure fnm(P : in out R_Matrix); -- R_Matrix is not visible
...
end nm;

nm.adb
package body nm is --Np still not known
Procedure fnm(P : in out R_Matrix) is
...
end fnm; -- R_Matrix not visible
end nm;

test_nm.adb
procedure test_nm is
-- Np known
-- instantiation of R_Matrix not possible as nm.ads has errors
Definitions for f;
call for fem;
end test_nm;

I have nm_G.ads, nm.ads, nm.adb and test_nm.adb, and I want to specify Np in test_nm.adb only, How can it be made possible ?

^ permalink raw reply	[relevance 5%]

* Re: Ada.Numerics.Long_Real_Arrays
  2017-01-25 12:25 12% Ada.Numerics.Long_Real_Arrays hnptz
  2017-01-25 13:50 11% ` Ada.Numerics.Long_Real_Arrays Simon Wright
  2017-01-25 14:11  6% ` Ada.Numerics.Long_Real_Arrays hnptz
@ 2017-01-25 18:35  6% ` hnptz
  2017-01-25 21:29  5% ` Ada.Numerics.Long_Real_Arrays hnptz
  2017-01-27 16:51 11% ` Ada.Numerics.Long_Real_Arrays hnptz
  4 siblings, 0 replies; 200+ results
From: hnptz @ 2017-01-25 18:35 UTC (permalink / raw)


On Wednesday, January 25, 2017 at 1:25:18 PM UTC+1, hn...@yahoo.de wrote:
> Hi,
> 
> these are my definitions:
> 
> with Ada.Numerics.Long_Real_Arrays; use Ada.Numerics.Long_Real_Arrays;
> package nm is
> 
> Np : Positive;
> Type R_Vector is new Real_Vector (1..Np);
> Type R_Matrix is array (Positive range <>) of R_Vector;
> 
> procedure nm1 (P : in out R_Matrix);
> 
> end nm;
> 
> -- definition of procedure nm1 in package body nm done.
> 
> now in procedure test_nm.adb (only definitions):
> 
> Np : Positive := 2;
> Mp : Positive := Np+1;
> 
> 24  P : R_Matrix(1..Mp) := ((x,x),(y,y),(z,z));
> 
> no "build all" error or warning
> 
> result when running:
> 
> raised CONSTRAINT_ERROR : test_nm.adb: 24 length check failed.
> 
> Can you help?

I was hesitating to use generic in this example, as it produces more code. I'm using generic procedure with function definition and supplementary instantiation anyway, and running out of sensible names is another issue concerning transparency and elegance. However, thanks for definitely pointing to a generic solution.

^ permalink raw reply	[relevance 6%]

* Re: Ada.Numerics.Long_Real_Arrays
  2017-01-25 14:11  6% ` Ada.Numerics.Long_Real_Arrays hnptz
@ 2017-01-25 16:17 13%   ` Simon Wright
  0 siblings, 0 replies; 200+ results
From: Simon Wright @ 2017-01-25 16:17 UTC (permalink / raw)


hnptz@yahoo.de writes:

> On Wednesday, January 25, 2017 at 1:25:18 PM UTC+1, hn...@yahoo.de wrote:
>> Hi,
>> 
>> these are my definitions:
>> 
>> with Ada.Numerics.Long_Real_Arrays; use Ada.Numerics.Long_Real_Arrays;
>> package nm is
>> 
>> Np : Positive;
>> Type R_Vector is new Real_Vector (1..Np);
>> Type R_Matrix is array (Positive range <>) of R_Vector;
>> 
>> procedure nm1 (P : in out R_Matrix);
>> 
>> end nm;

> First, I want to keep the length of P open until I fix it in
> test_nm.adb. The length of R_Vector is always Mp-1.  Second, I want to
> use the builtin Real_Vector arithmetic, that I do not have to resort
> to loops. Using Real_Matrix definitions won't allow it, as slices of
> n-dimensional arrays are not possible.

You could try a generic?

with Ada.Numerics.Long_Real_Arrays;
generic
   Rows : Positive;
package Nm_G is
   subtype R_Vector
     is Ada.Numerics.Long_Real_Arrays.Real_Vector (1 .. Rows - 1);
   type R_Matrix is array (1 .. Rows) of R_Vector;
end Nm_G;

with Ada.Text_Io; use Ada.Text_Io;
with Nm_G;
procedure Nm_Test is
   package Nm is new Nm_G (Rows => 3);
   use Nm;
   P : R_Matrix := ((42.0, 42.0), (43.0, 43.0), (44.0, 44.0));
   V : R_Vector := P (P'Last);
begin
   Put_Line ("v: " & V (V'First)'Img & ", " & V (V'Last)'Img);
end Nm_Test;

^ permalink raw reply	[relevance 13%]

* Re: Ada.Numerics.Long_Real_Arrays
  2017-01-25 12:25 12% Ada.Numerics.Long_Real_Arrays hnptz
  2017-01-25 13:50 11% ` Ada.Numerics.Long_Real_Arrays Simon Wright
@ 2017-01-25 14:11  6% ` hnptz
  2017-01-25 16:17 13%   ` Ada.Numerics.Long_Real_Arrays Simon Wright
  2017-01-25 18:35  6% ` Ada.Numerics.Long_Real_Arrays hnptz
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 200+ results
From: hnptz @ 2017-01-25 14:11 UTC (permalink / raw)


On Wednesday, January 25, 2017 at 1:25:18 PM UTC+1, hn...@yahoo.de wrote:
> Hi,
> 
> these are my definitions:
> 
> with Ada.Numerics.Long_Real_Arrays; use Ada.Numerics.Long_Real_Arrays;
> package nm is
> 
> Np : Positive;
> Type R_Vector is new Real_Vector (1..Np);
> Type R_Matrix is array (Positive range <>) of R_Vector;
> 
> procedure nm1 (P : in out R_Matrix);
> 
> end nm;
> 
> -- definition of procedure nm1 in package body nm done.
> 
> now in procedure test_nm.adb (only definitions):
> 
> Np : Positive := 2;
> Mp : Positive := Np+1;
> 
> 24  P : R_Matrix(1..Mp) := ((x,x),(y,y),(z,z));
> 
> no "build all" error or warning
> 
> result when running:
> 
> raised CONSTRAINT_ERROR : test_nm.adb: 24 length check failed.
> 
> Can you help?

First, I want to keep the length of P open until I fix it in test_nm.adb. The length of R_Vector is always Mp-1.
Second, I want to use the builtin Real_Vector arithmetic, that I do not have to resort to loops. Using Real_Matrix definitions won't allow it, as slices of n-dimensional arrays are not possible.

^ permalink raw reply	[relevance 6%]

* Re: Ada.Numerics.Long_Real_Arrays
  2017-01-25 12:25 12% Ada.Numerics.Long_Real_Arrays hnptz
@ 2017-01-25 13:50 11% ` Simon Wright
  2017-01-25 14:11  6% ` Ada.Numerics.Long_Real_Arrays hnptz
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 200+ results
From: Simon Wright @ 2017-01-25 13:50 UTC (permalink / raw)


hnptz@yahoo.de writes:

> with Ada.Numerics.Long_Real_Arrays; use Ada.Numerics.Long_Real_Arrays;
> package nm is
>
> Np : Positive;

So what value does Np have at this point?

> Type R_Vector is new Real_Vector (1..Np);

Np here will have whatever value it has been assigned by the compiler;
on my system, it was 0 (which isn't valid for Positive, but I expect the
compiler is allowed to make an undefined value whatver is convenient for
it).

> Type R_Matrix is array (Positive range <>) of R_Vector;
>
> procedure nm1 (P : in out R_Matrix);
>
> end nm;

> now in procedure test_nm.adb (only definitions):
>
> Np : Positive := 2;

This is a local declaration which hides Nm.Np (even if you "use Nm;");
setting a value here has no effect on Nm.Np.

> Mp : Positive := Np+1;
>
> 24  P : R_Matrix(1..Mp) := ((x,x),(y,y),(z,z));
>
> no "build all" error or warning

Because it's quite legal to have an array with index range 1 .. 0 -- it
just means it's empty (zero length).

> result when running:
>
> raised CONSTRAINT_ERROR : test_nm.adb: 24 length check failed.

Why not use Ada.Numerics.Long_Real_Arrays.Real_Matrix?

^ permalink raw reply	[relevance 11%]

* Ada.Numerics.Long_Real_Arrays
@ 2017-01-25 12:25 12% hnptz
  2017-01-25 13:50 11% ` Ada.Numerics.Long_Real_Arrays Simon Wright
                   ` (4 more replies)
  0 siblings, 5 replies; 200+ results
From: hnptz @ 2017-01-25 12:25 UTC (permalink / raw)


Hi,

these are my definitions:

with Ada.Numerics.Long_Real_Arrays; use Ada.Numerics.Long_Real_Arrays;
package nm is

Np : Positive;
Type R_Vector is new Real_Vector (1..Np);
Type R_Matrix is array (Positive range <>) of R_Vector;

procedure nm1 (P : in out R_Matrix);

end nm;

-- definition of procedure nm1 in package body nm done.

now in procedure test_nm.adb (only definitions):

Np : Positive := 2;
Mp : Positive := Np+1;

24  P : R_Matrix(1..Mp) := ((x,x),(y,y),(z,z));

no "build all" error or warning

result when running:

raised CONSTRAINT_ERROR : test_nm.adb: 24 length check failed.

Can you help?

^ permalink raw reply	[relevance 12%]

* Ok to assume type Duration is for more than one day?
@ 2017-01-22 11:37  6% reinkor
  0 siblings, 0 replies; 200+ results
From: reinkor @ 2017-01-22 11:37 UTC (permalink / raw)


As I understand from my textbook, type Duration is guaranteed to cover the range -86_400 .. 86_400 (number of seconds for one day). Does this mean that I take a considerable risk if I assume "Duration" can represent more than one day?

The following program:

----------------------------------------------------------------
with Ada.Numerics.Generic_Elementary_Functions,Text_IO;
use Text_IO;
with Ada.Calendar; use Ada.Calendar;

procedure d1 is

   package Flt_Io is new Text_IO.Float_Io   (Float);
   package Int_Io is new Text_IO.Integer_Io (Integer);
   package E_F is new Ada.Numerics.Generic_Elementary_Functions (Float);
   use E_F,Flt_Io,Int_Io;

   d : Duration := Duration(3600*24*10);

begin

   Put(" Duration'Last : ");
   Put(Float(Duration'Last)/(3600.0*24.0*365.0),20,1,0);

end d1;
--------------------------------------------------------------

gives (gnat/debian and also Raspberry Pi (Raspbian)):

Duration'Last :                  292.5

(i.e. many years....).

reinert

^ permalink raw reply	[relevance 6%]

* Re: Interfacing Ada With Full Runtime Directly to Electronic Chips
  2017-01-04 20:51  0%     ` Simon Wright
@ 2017-01-04 22:05  0%       ` antispam
  0 siblings, 0 replies; 200+ results
From: antispam @ 2017-01-04 22:05 UTC (permalink / raw)


Simon Wright <simon@pushface.org> wrote:
> antispam@math.uni.wroc.pl writes:
> 
> > Simon Wright <simon@pushface.org> wrote:
> >> 
> >> Both of the above use OS device support via file read/write/ioctl. If
> >> you want to go bare(ish) metal, there is the AdaCore Ada_Drivers_Library
> >> at [4]. This uses cross-compilation for ARM Cortex MCUs, compilers from
> >> AdaCore (or [5], [6] for Mac), with runtimes for boards mostly from
> >> STMicroelectronics (e.g. [7]).
> >> 
> >> The AdaCore runtimes support Ravenscar tasking[8] and come in two
> >> flavours, small footprint (-sfp-) and full (-full-). The -full- version
> >> supports exception handling and finalization and includes
> >> Ada.Numerics. Neither support containers (easy enough to copy into the
> >> -full- version, I expect).
> >> 
> >> The Ada_Drivers_Library uses a BSD license. The AdaCore runtimes use a
> >> full-GPL license. If this matters to you I have runtimes for Arduino Due
> >> and STM32F4[9] which are based on FreeRTOS and have the GCC Runtime
> >> Library Exception, allowing release of code on proprietary terms.
> >
> > IIUC STM runtimes are incompatible with GPL.  So combining them
> > with GPL runtime means that result can not be distributed at
> > all.
> 
> Do you have a reference for this? the STM source licence that I see in
> the STM32Cube firmware releases imposes very few restrictions on the
> actual use of the software, only requiring inclusion of the STM
> copyright notice. There's nothing like the restriction quoted in [1].
> 
> But in any case the RTS I'm talking about doesn't use any STM code, just
> FreeRTOS. Which uses a GPLv2 licence, which doesn't include the usual
> "or later version" test. Which may be a problem.
> 
> [1] https://github.com/d-ronin/dRonin/issues/928

I did not look at STM32Cube (they make download awkward and I do
not need most of it).  Most of parts that I was able to
download outside of STM32Cube contain the restriction to
STM devices mentioned in [1].  AFAICS some STM libraries
are only available as C headers + binary blob.

Good to hear that you are independent of STM code.

-- 
                              Waldek Hebisch

^ permalink raw reply	[relevance 0%]

* Re: Interfacing Ada With Full Runtime Directly to Electronic Chips
  2017-01-04 19:29  0%   ` antispam
@ 2017-01-04 20:51  0%     ` Simon Wright
  2017-01-04 22:05  0%       ` antispam
  0 siblings, 1 reply; 200+ results
From: Simon Wright @ 2017-01-04 20:51 UTC (permalink / raw)


antispam@math.uni.wroc.pl writes:

> Simon Wright <simon@pushface.org> wrote:
>> 
>> Both of the above use OS device support via file read/write/ioctl. If
>> you want to go bare(ish) metal, there is the AdaCore Ada_Drivers_Library
>> at [4]. This uses cross-compilation for ARM Cortex MCUs, compilers from
>> AdaCore (or [5], [6] for Mac), with runtimes for boards mostly from
>> STMicroelectronics (e.g. [7]).
>> 
>> The AdaCore runtimes support Ravenscar tasking[8] and come in two
>> flavours, small footprint (-sfp-) and full (-full-). The -full- version
>> supports exception handling and finalization and includes
>> Ada.Numerics. Neither support containers (easy enough to copy into the
>> -full- version, I expect).
>> 
>> The Ada_Drivers_Library uses a BSD license. The AdaCore runtimes use a
>> full-GPL license. If this matters to you I have runtimes for Arduino Due
>> and STM32F4[9] which are based on FreeRTOS and have the GCC Runtime
>> Library Exception, allowing release of code on proprietary terms.
>
> IIUC STM runtimes are incompatible with GPL.  So combining them
> with GPL runtime means that result can not be distributed at
> all.

Do you have a reference for this? the STM source licence that I see in
the STM32Cube firmware releases imposes very few restrictions on the
actual use of the software, only requiring inclusion of the STM
copyright notice. There's nothing like the restriction quoted in [1].

But in any case the RTS I'm talking about doesn't use any STM code, just
FreeRTOS. Which uses a GPLv2 licence, which doesn't include the usual
"or later version" test. Which may be a problem.

[1] https://github.com/d-ronin/dRonin/issues/928


^ permalink raw reply	[relevance 0%]

* Re: Interfacing Ada With Full Runtime Directly to Electronic Chips
  2017-01-02 16:25  3% ` Simon Wright
@ 2017-01-04 19:29  0%   ` antispam
  2017-01-04 20:51  0%     ` Simon Wright
  0 siblings, 1 reply; 200+ results
From: antispam @ 2017-01-04 19:29 UTC (permalink / raw)


Simon Wright <simon@pushface.org> wrote:
> 
> Both of the above use OS device support via file read/write/ioctl. If
> you want to go bare(ish) metal, there is the AdaCore Ada_Drivers_Library
> at [4]. This uses cross-compilation for ARM Cortex MCUs, compilers from
> AdaCore (or [5], [6] for Mac), with runtimes for boards mostly from
> STMicroelectronics (e.g. [7]).
> 
> The AdaCore runtimes support Ravenscar tasking[8] and come in two
> flavours, small footprint (-sfp-) and full (-full-). The -full- version
> supports exception handling and finalization and includes
> Ada.Numerics. Neither support containers (easy enough to copy into the
> -full- version, I expect).
> 
> The Ada_Drivers_Library uses a BSD license. The AdaCore runtimes use a
> full-GPL license. If this matters to you I have runtimes for Arduino Due
> and STM32F4[9] which are based on FreeRTOS and have the GCC Runtime
> Library Exception, allowing release of code on proprietary terms.

IIUC STM runtimes are incompatible with GPL.  So combining them
with GPL runtime means that result can not be distributed at
all.

-- 
                              Waldek Hebisch

^ permalink raw reply	[relevance 0%]

* Re: Interfacing Ada With Full Runtime Directly to Electronic Chips
  @ 2017-01-02 16:25  3% ` Simon Wright
  2017-01-04 19:29  0%   ` antispam
  0 siblings, 1 reply; 200+ results
From: Simon Wright @ 2017-01-02 16:25 UTC (permalink / raw)


patrick@spellingbeewinnars.org writes:

> If I want to connect any sort of computer running Linux directly to a
> circuit using "full Ada" with tasking support what are my options?
>
> By circuit, I mean a variety of electronic components and in this case
> with no microcontroller, an A/D chip is a simple example.
>
> I am thinking that single board computers like BeagleBone are my best
> bet, they have plenty of GPIO lines.
>
> Has anyone interfaced directly with chips via SPI or IC2 via a GPIO
> PCI card or GPIO-USB adapter ?
>
> Is there any other options?

You can talk I2C from a Raspberry Pi; see [1], [2]. It was simple to
install GNAT etc from libre.adacore.com, since Raspbian is a Debian
offshoot.

Beaglebone also supports Debian, see [3] for a report on this.

Both of the above use OS device support via file read/write/ioctl. If
you want to go bare(ish) metal, there is the AdaCore Ada_Drivers_Library
at [4]. This uses cross-compilation for ARM Cortex MCUs, compilers from
AdaCore (or [5], [6] for Mac), with runtimes for boards mostly from
STMicroelectronics (e.g. [7]).

The AdaCore runtimes support Ravenscar tasking[8] and come in two
flavours, small footprint (-sfp-) and full (-full-). The -full- version
supports exception handling and finalization and includes
Ada.Numerics. Neither support containers (easy enough to copy into the
-full- version, I expect).

The Ada_Drivers_Library uses a BSD license. The AdaCore runtimes use a
full-GPL license. If this matters to you I have runtimes for Arduino Due
and STM32F4[9] which are based on FreeRTOS and have the GCC Runtime
Library Exception, allowing release of code on proprietary terms.

Just to indicate the flavour of this bare-metal code, I have some SPI
code for an STM32F427, using interface code generated by AdaCore's
SVD2Ada[10], at [11].

[1] https://sourceforge.net/projects/raspi-i2c-ada/
[2] http://raspi-i2c-ada.sourceforge.net
[3] https://groups.google.com/forum/#!topic/beagleboard/O5AU2XL6NJ8
[4] https://github.com/AdaCore/Ada_Drivers_Library
[5] https://sourceforge.net/projects/gnuada/files/GNAT_GPL%20Mac%20OS%20X/2016-arm-eabi-darwin-bin/
[6] https://sourceforge.net/projects/gnuada/files/GNAT_GCC%20Mac%20OS%20X/6.1.0/arm-eabi/
[7]
http://uk.farnell.com/stmicroelectronics/stm32f407g-disc1/dev-board-foundation-line-mcu/dp/2506840
[8] https://en.wikipedia.org/wiki/Ravenscar_profile
[9] https://sourceforge.net/projects/cortex-gnat-rts/
[10] https://github.com/AdaCore/svd2ada
[11] https://github.com/simonjwright/multiplexed-io/blob/master/drivers/spi1/src/spi1-device.adb


^ permalink raw reply	[relevance 3%]

* Re: Trigonometric operations on x86 and x64 CPUs
  @ 2016-12-16 20:50  5% ` Vadim Godunko
  0 siblings, 0 replies; 200+ results
From: Vadim Godunko @ 2016-12-16 20:50 UTC (permalink / raw)


Don't understand what are you worry about.

I suppose all (too lazy to check ALL instructions) floating point instructions are supported in 64-bit code. GNAT's RTL do all necessary software preprocessing to obtain good precision. OS do all necessary context store/restore operations on task/process switching. You need just to instantiate Ada.Numerics.Generic_Elementary_Functions and use it. ;)


^ permalink raw reply	[relevance 5%]

* Re: matrix manipulation
  @ 2016-11-15 17:54  4%     ` Stephen Leake
  0 siblings, 0 replies; 200+ results
From: Stephen Leake @ 2016-11-15 17:54 UTC (permalink / raw)


On Monday, November 14, 2016 at 11:39:56 AM UTC-6, hn...@yahoo.de wrote:
> On Sunday, November 13, 2016 at 12:30:16 AM UTC+1, Stephen Leake wrote:
> > On Saturday, November 12, 2016 at 12:16:47 PM UTC-6, hn...@yahoo.de wrote:
> > > What is an elegant way to program exchange of columns in a matrix. 
> > > Application: 
> > > C is a matrix. Cj be the j-th column of C.
> > > Sort C1,C2, ..., Cn in non increasing order with respect to their first component.
> > > I tried and ended up in a very messy program, as I had to sort the first components first, remember their new index and then reconstruct the matrix.
> > 
> > declare the matrix as an array of columns:
> > 
> > type Column is array (1 .. 10) of float;
> > type Matrix is array (1 .. 10) of Column;
> > 
> > A : Matrix := ...;
> > Tmp : Column;
> > 
> > Tmp := A (2);
> > A (2) := A (1);
> > A (1) := Tmp;
> 
> How to access a single element of matrix A ? Is it A(1)(1) ? 

Yes.

> I think, I cannot use it as a Matrix anymore applying build in 
> Ada-procedures, like for solving  equations or transposing the matrix. I 
> would have to transform it into a 2-dimensional array, right ?

I guess you mean the type Ada.Numerics.Generic_Complex_Arrays.Complex_Matrix, or something similar.

It helps to have _all_ of the requirements at hand when designing a solution :)

You have two choices here; write code two swap two rows of a 2D array, or copy the 2D array to an array of arrays, swap, and copy back. You'd have to measure to be sure which is more efficient, and the result will depend on matrix size.

For an initial design, it is best to go with code that is easiest to understand and implement; get it right first, then measure it, then improve only if necessary.


^ permalink raw reply	[relevance 4%]

* Re: Ada.Numerics, Accuracy of trigonometric functions
  2016-10-07 10:13  9% Ada.Numerics, Accuracy of trigonometric functions Markus Schöpflin
                   ` (3 preceding siblings ...)
  2016-10-07 16:38 10% ` Jeffrey R. Carter
@ 2016-10-22 22:38  9% ` Robert Eachus
  4 siblings, 0 replies; 200+ results
From: Robert Eachus @ 2016-10-22 22:38 UTC (permalink / raw)


On Friday, October 7, 2016 at 6:13:50 AM UTC-4, Markus Schöpflin wrote:

> I'm puzzled by the seemingly bad accuracy of calling COS on a large value of type Short_Float.
> 
> Given the following procedure which calculates y1 = cos(2**32) and y2 = 
> cos(2**32 mod 2*PI):
 
> Now for the questions: Is my reasoning above correct? Why does using the cycle 
> parameter not help? Do other Ada compilers give the same bad result in this 
> case? Should I report this as an error to AdaCore?

Yes, you should report this as an error to AdaCore.  The correct fix is to raise Constraint_Error, and mention why in the documentation.   I'd like to raise Argument_Error, but even mentioning that possibility may result in lots more posts than the issue is worth.

I tried your program both with Short and Long_Float, and values of X up to 2**32 with and without scaling.  The unscaled numbers worked up perfectly until 2**32 (see below).  There seems to be some rounding somewhere in the scaled version.  It's fine up to about 2**20.  The unscaled numbers are accurate to 14 digits up until 2**32:
Size of Long_FLOAT =  64
Maximum relative error of COS =  4.44089209850063E-16
Angle threshold =  26
X**I =          1.00; COS(X**I) =  0.54030230586814; Scaled Cos = 0.54030230586814
X**I =          2.00; COS(X**I) = -0.41614683654714; Scaled Cos =-0.41614683654714
X**I =          4.00; COS(X**I) = -0.65364362086361; Scaled Cos =-0.65364362086361
X**I =          8.00; COS(X**I) = -0.14550003380861; Scaled Cos =-0.14550003380861
X**I =         16.00; COS(X**I) = -0.95765948032338; Scaled Cos =-0.95765948032338
X**I =         32.00; COS(X**I) =  0.83422336050651; Scaled Cos = 0.83422336050651
X**I =         64.00; COS(X**I) =  0.39185723042955; Scaled Cos = 0.39185723042955
X**I =        128.00; COS(X**I) = -0.69289582192017; Scaled Cos =-0.69289582192017
X**I =        256.00; COS(X**I) = -0.03979075993116; Scaled Cos =-0.03979075993116
X**I =        512.00; COS(X**I) = -0.99683339084820; Scaled Cos =-0.99683339084820
X**I =       1024.00; COS(X**I) =  0.98735361821985; Scaled Cos = 0.98735361821985
X**I =       2048.00; COS(X**I) =  0.94973433482365; Scaled Cos = 0.94973433482365
X**I =       4096.00; COS(X**I) =  0.80399061348585; Scaled Cos = 0.80399061348585
X**I =       8192.00; COS(X**I) =  0.29280181314670; Scaled Cos = 0.29280181314670
X**I =      16384.00; COS(X**I) = -0.82853419643601; Scaled Cos =-0.82853419643601
X**I =      32768.00; COS(X**I) =  0.37293782932771; Scaled Cos = 0.37293782932771
X**I =      65536.00; COS(X**I) = -0.72183475091266; Scaled Cos =-0.72183475091266
X**I =     131072.00; COS(X**I) =  0.04209081525030; Scaled Cos = 0.04209081525030
X**I =     262144.00; COS(X**I) = -0.99645672654313; Scaled Cos =-0.99645672654313
X**I =     524288.00; COS(X**I) =  0.98585201574610; Scaled Cos = 0.98585201574611
X**I =    1048576.00; COS(X**I) =  0.94380839390131; Scaled Cos = 0.94380839390132
X**I =    2097152.00; COS(X**I) =  0.78154856879715; Scaled Cos = 0.78154856879720
X**I =    4194304.00; COS(X**I) =  0.22163633077774; Scaled Cos = 0.22163633077789
X**I =    8388608.00; COS(X**I) = -0.90175467375876; Scaled Cos =-0.90175467375863
X**I =   16777216.00; COS(X**I) =  0.62632298329153; Scaled Cos = 0.62632298329196
X**I =   33554432.00; COS(X**I) = -0.21543904120159; Scaled Cos =-0.21543904120051
X**I =   67108864.00; COS(X**I) = -0.90717203905228; Scaled Cos =-0.90717203905196
X**I =  134217728.00; COS(X**I) =  0.64592221687655; Scaled Cos = 0.64592221687210
X**I =  268435456.00; COS(X**I) = -0.16556897949058; Scaled Cos =-0.16556897950206
X**I =  536870912.00; COS(X**I) = -0.94517382606090; Scaled Cos =-0.94517382605945
X**I = 1073741824.00; COS(X**I) =  0.78670712294119; Scaled Cos = 0.78670712290611
X**I = 2147483648.00; COS(X**I) =  0.23781619457280; Scaled Cos = 0.23781619446243
X**I = 4294967296.00; COS(X**I) =  1.00000000000000; Scaled Cos =-0.88688691530282
[2016-10-22 18:28:01] process terminated successfully, elapsed time: 00.34s

with ADA.NUMERICS.GENERIC_ELEMENTARY_FUNCTIONS; 

with ADA.TEXT_IO; use ADA.TEXT_IO; 
with ADA.Long_FLOAT_TEXT_IO; use ADA.Long_FLOAT_TEXT_IO; 

procedure TEST_TRIG is 

    MRE_COS : constant := 2.0 * Long_FLOAT'MODEL_EPSILON; 
    THRESHOLD : constant := Long_FLOAT'MACHINE_MANTISSA / 2; 
   Pi : constant := Ada.Numerics.Pi;
   Two_Pi : constant := Pi + Pi;
    package EF is new ADA.NUMERICS.GENERIC_ELEMENTARY_FUNCTIONS (Long_FLOAT); 

   X : constant Long_FLOAT := 2.0;
   Temp: Integer;
    Y : constant Long_FLOAT := EF.COS (X); 

begin 

    PUT_LINE ("Size of Long_FLOAT = " & POSITIVE'IMAGE (Long_FLOAT'SIZE)); 
    PUT_LINE ("Maximum relative error of COS = " & Long_FLOAT'IMAGE (MRE_COS)); 
    PUT_LINE ("Angle threshold = " & POSITIVE'IMAGE (THRESHOLD)); 

    for I in 0..32 loop
      PUT ("X**I = ");        PUT (X**I, Fore => 10, Aft => 2, EXP => 0); 
      PUT ("; COS(X**I) = "); PUT (EF.Cos(X**I), EXP => 0);
      Temp := Integer(X**I/(2.0*Pi));
      Put ("; Scaled Cos =");
      PUT (EF.Cos(Long_Float(Long_Long_Float(X**I)
            - Long_Long_Float'(Long_Long_Float(Temp)*Two_Pi))), EXP => 0);
      NEW_LINE;
      
    end loop;


end TEST_TRIG;

^ permalink raw reply	[relevance 9%]

* Re: Ada.Numerics, Accuracy of trigonometric functions
  2016-10-07 16:38 10% ` Jeffrey R. Carter
@ 2016-10-10  7:44  6%   ` Markus Schöpflin
  0 siblings, 0 replies; 200+ results
From: Markus Schöpflin @ 2016-10-10  7:44 UTC (permalink / raw)


Am 07.10.2016 um 18:38 schrieb Jeffrey R. Carter:

> It looks to me as if Reduce is converting X to zero, which is then passed
> to fcos, giving 1.
>
> This result is independent of the actual type used to instantiate
> Generic_Elementary_Functions.

This explains a lot, then.

Thank you very much,
Markus


^ permalink raw reply	[relevance 6%]

* Re: Ada.Numerics, Accuracy of trigonometric functions
  2016-10-07 15:19  6%   ` Markus Schöpflin
@ 2016-10-07 22:15  6%     ` Dennis Lee Bieber
  0 siblings, 0 replies; 200+ results
From: Dennis Lee Bieber @ 2016-10-07 22:15 UTC (permalink / raw)


On Fri, 7 Oct 2016 17:19:09 +0200, Markus Schöpflin <no.spam@spam.spam>
declaimed the following:

>Am 07.10.2016 um 16:52 schrieb Dennis Lee Bieber:
>> On Fri, 7 Oct 2016 12:13:48 +0200, Markus Schöpflin <no.spam@spam.spam>
>> declaimed the following:
>>
>>
>>> X = 4294967296.00000; COS(X) =  1.00000      <-- WHAT?
>>
>> 	That kind of surprises me...  Not the cos() result, but the input X
>>
>> 	Short float should only have around 23-24 bits of significance in the
>> mantissa -- enough for around 7 decimal digits. Yet you are seeing the full
>> UNSIGNED 32-bit integer value with a stack of fractional zeros tacked on.
>>
>> 	I'm tempted to think the compiler, not the run-time, is computing the
>> 2^32 as a universal (or whatever the preferred term is)  constant using the
>> smallest data type that holds the full value.
>>
>
>2**32 has an exact representation as short float: 0x4f800000 (in binary this 
>is 0 10011111 00000000000000000000000; sign 0, exponent 159, mantissa 0).
>
>Markus

	Ah... One of those magic numbers then...
-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
    wlfraed@ix.netcom.com    HTTP://wlfraed.home.netcom.com/

^ permalink raw reply	[relevance 6%]

* Re: Ada.Numerics, Accuracy of trigonometric functions
  2016-10-07 10:13  9% Ada.Numerics, Accuracy of trigonometric functions Markus Schöpflin
                   ` (2 preceding siblings ...)
  2016-10-07 14:52  5% ` Dennis Lee Bieber
@ 2016-10-07 16:38 10% ` Jeffrey R. Carter
  2016-10-10  7:44  6%   ` Markus Schöpflin
  2016-10-22 22:38  9% ` Robert Eachus
  4 siblings, 1 reply; 200+ results
From: Jeffrey R. Carter @ 2016-10-07 16:38 UTC (permalink / raw)


On 10/07/2016 03:13 AM, Markus Schöpflin wrote:
>
> Size of SHORT_FLOAT =  32
> Maximum relative error of COS =  2.38419E-07
> Angle threshold =  12
> X = 4294967296.00000; COS(X) =  1.00000      <-- WHAT?

For GNAT (I have 4.9.3) Ada.Numerics.Generic_Elementary_Functions is defined in 
terms of Ada.Numerics.Aux, which defines

type Double is new Long_Long_Float;

Cos, after some checks for zero, converts its argument to Double and calls 
Aux.Cos. Aux.Cos, for abs X > Pi/4, reduces abs X and then invokes the FPU 
instruction fcos or fsin on the reduced value, depending on the quadrant.

Reduce is defined as

    procedure Reduce (X : in out Double; Q : out Natural);
    --  Implements reduction of X by Pi/2. Q is the quadrant of the final
    --  result in the range 0 .. 3. The absolute value of X is at most Pi.

and contains the following

       K  : Double := X * Two_Over_Pi;
    begin
       --  For X < 2.0**32, all products below are computed exactly.
       --  Due to cancellation effects all subtractions are exact as well.
       --  As no double extended floating-point number has more than 75
       --  zeros after the binary point, the result will be the correctly
       --  rounded result of X - K * (Pi / 2.0).

Since X = 2**32, this doesn't apply. It looks to me as if Reduce is converting X 
to zero, which is then passed to fcos, giving 1.

This result is independent of the actual type used to instantiate 
Generic_Elementary_Functions.

The C cosf function probably just passes its argument to fcos.

Investigation of what GNAT does for Cos with Cycle is left as an exercise for 
the reader.

-- 
Jeff Carter
"It's symbolic of his struggle against reality."
Monty Python's Life of Brian
78

^ permalink raw reply	[relevance 10%]

* Re: Ada.Numerics, Accuracy of trigonometric functions
  2016-10-07 14:52  5% ` Dennis Lee Bieber
@ 2016-10-07 15:19  6%   ` Markus Schöpflin
  2016-10-07 22:15  6%     ` Dennis Lee Bieber
  0 siblings, 1 reply; 200+ results
From: Markus Schöpflin @ 2016-10-07 15:19 UTC (permalink / raw)


Am 07.10.2016 um 16:52 schrieb Dennis Lee Bieber:
> On Fri, 7 Oct 2016 12:13:48 +0200, Markus Schöpflin <no.spam@spam.spam>
> declaimed the following:
>
>
>> X = 4294967296.00000; COS(X) =  1.00000      <-- WHAT?
>
> 	That kind of surprises me...  Not the cos() result, but the input X
>
> 	Short float should only have around 23-24 bits of significance in the
> mantissa -- enough for around 7 decimal digits. Yet you are seeing the full
> UNSIGNED 32-bit integer value with a stack of fractional zeros tacked on.
>
> 	I'm tempted to think the compiler, not the run-time, is computing the
> 2^32 as a universal (or whatever the preferred term is)  constant using the
> smallest data type that holds the full value.
>

2**32 has an exact representation as short float: 0x4f800000 (in binary this 
is 0 10011111 00000000000000000000000; sign 0, exponent 159, mantissa 0).

Markus

^ permalink raw reply	[relevance 6%]

* Re: Ada.Numerics, Accuracy of trigonometric functions
  2016-10-07 10:13  9% Ada.Numerics, Accuracy of trigonometric functions Markus Schöpflin
  2016-10-07 10:23  6% ` Markus Schöpflin
  2016-10-07 10:23  6% ` Brian Drummond
@ 2016-10-07 14:52  5% ` Dennis Lee Bieber
  2016-10-07 15:19  6%   ` Markus Schöpflin
  2016-10-07 16:38 10% ` Jeffrey R. Carter
  2016-10-22 22:38  9% ` Robert Eachus
  4 siblings, 1 reply; 200+ results
From: Dennis Lee Bieber @ 2016-10-07 14:52 UTC (permalink / raw)


On Fri, 7 Oct 2016 12:13:48 +0200, Markus Schöpflin <no.spam@spam.spam>
declaimed the following:


>X = 4294967296.00000; COS(X) =  1.00000      <-- WHAT?

	That kind of surprises me...  Not the cos() result, but the input X

	Short float should only have around 23-24 bits of significance in the
mantissa -- enough for around 7 decimal digits. Yet you are seeing the full
UNSIGNED 32-bit integer value with a stack of fractional zeros tacked on.

	I'm tempted to think the compiler, not the run-time, is computing the
2^32 as a universal (or whatever the preferred term is)  constant using the
smallest data type that holds the full value.
-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
    wlfraed@ix.netcom.com    HTTP://wlfraed.home.netcom.com/


^ permalink raw reply	[relevance 5%]

* Re: Ada.Numerics, Accuracy of trigonometric functions
  2016-10-07 10:23  6% ` Brian Drummond
@ 2016-10-07 10:40  6%   ` Markus Schöpflin
  0 siblings, 0 replies; 200+ results
From: Markus Schöpflin @ 2016-10-07 10:40 UTC (permalink / raw)


Am 07.10.2016 um 12:23 schrieb Brian Drummond:

[...]

> C tends to silently coerce "float" to "double" any time you pass a float
> argument to a function unless you jump through hoops to make such
> coercion impossible.
>
> So my suspicion is simply that the C program is giving you double
> precision.

I can see in the generated assembler dump that the libc cosf function is 
called. So I don't think this is the case.

And I get the same result in Ada using Long_Float or Long_Long_Float; see my 
follow-up.

Markus

^ permalink raw reply	[relevance 6%]

* Re: Ada.Numerics, Accuracy of trigonometric functions
  2016-10-07 10:13  9% Ada.Numerics, Accuracy of trigonometric functions Markus Schöpflin
  2016-10-07 10:23  6% ` Markus Schöpflin
@ 2016-10-07 10:23  6% ` Brian Drummond
  2016-10-07 10:40  6%   ` Markus Schöpflin
  2016-10-07 14:52  5% ` Dennis Lee Bieber
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 200+ results
From: Brian Drummond @ 2016-10-07 10:23 UTC (permalink / raw)


On Fri, 07 Oct 2016 12:13:48 +0200, Markus Schöpflin wrote:

> The following tests have been performed using GNAT 7.4 on a 64bit Linux
> system.
> 
> I'm puzzled by the seemingly bad accuracy of calling COS on a large
> value of type Short_Float.
> 
> ---%<---
> Size of SHORT_FLOAT =  32 Maximum relative error of COS =  2.38419E-07
> Angle threshold =  12 X = 4294967296.00000; COS(X) =  1.00000      <--
> WHAT?
> --->%---
> 
> The corresponding C program:
> 
> ---%<---
> 
> gives:
> 
> ---%<---
> sizeof(float) = 4 x = 4294967296.000000; cos(x) = -0.886887    <--- OK
> --->%---
> 
> Now, why is the error on cos(2**32) so large in this case? I am aware
> that I'm way beyond the required angle threshold mentioned in G.2.4(12),
> so it's up to the compiler to decide on the accuracy.

C tends to silently coerce "float" to "double" any time you pass a float 
argument to a function unless you jump through hoops to make such 
coercion impossible. 

So my suspicion is simply that the C program is giving you double 
precision.

-- Brian

^ permalink raw reply	[relevance 6%]

* Re: Ada.Numerics, Accuracy of trigonometric functions
  2016-10-07 10:13  9% Ada.Numerics, Accuracy of trigonometric functions Markus Schöpflin
@ 2016-10-07 10:23  6% ` Markus Schöpflin
  2016-10-07 10:23  6% ` Brian Drummond
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 200+ results
From: Markus Schöpflin @ 2016-10-07 10:23 UTC (permalink / raw)


What I forgot to add is that the results are the same using SHORT_FLOAT, 
LONG_FLOAT, or LONG_LONG_FLOAT when calling cos(x) without the cycle parameter.

But when adding the cycle parameter, LONG_FLOAT and LONG_LONG_FLOAT yield 
correct results, only SHORT_FLOAT is still wrong.

Markus


^ permalink raw reply	[relevance 6%]

* Ada.Numerics, Accuracy of trigonometric functions
@ 2016-10-07 10:13  9% Markus Schöpflin
  2016-10-07 10:23  6% ` Markus Schöpflin
                   ` (4 more replies)
  0 siblings, 5 replies; 200+ results
From: Markus Schöpflin @ 2016-10-07 10:13 UTC (permalink / raw)


The following tests have been performed using GNAT 7.4 on a 64bit Linux system.

I'm puzzled by the seemingly bad accuracy of calling COS on a large value of 
type Short_Float.

Given the following procedure which calculates y1 = cos(2**32) and y2 = 
cos(2**32 mod 2*PI):

---%<---
with ADA.NUMERICS.GENERIC_ELEMENTARY_FUNCTIONS;

with ADA.TEXT_IO; use ADA.TEXT_IO;
with ADA.SHORT_FLOAT_TEXT_IO; use ADA.SHORT_FLOAT_TEXT_IO;

procedure TEST_TRIG is

    MRE_COS : constant := 2.0 * SHORT_FLOAT'MODEL_EPSILON;
    THRESHOLD : constant := SHORT_FLOAT'MACHINE_MANTISSA / 2;

    package EF is new ADA.NUMERICS.GENERIC_ELEMENTARY_FUNCTIONS (SHORT_FLOAT);

    X : constant SHORT_FLOAT := 2.0**32;
    Y : constant SHORT_FLOAT := EF.COS (X);

begin

    PUT_LINE ("Size of SHORT_FLOAT = " & POSITIVE'IMAGE (SHORT_FLOAT'SIZE));
    PUT_LINE ("Maximum relative error of COS = " & SHORT_FLOAT'IMAGE (MRE_COS));
    PUT_LINE ("Angle threshold = " & POSITIVE'IMAGE (THRESHOLD));

    PUT ("X = ");        PUT (X, EXP => 0);
    PUT ("; COS(X) = "); PUT (Y, EXP => 0);
    NEW_LINE;

end TEST_TRIG;
--->%---

The (for me surprising result is):

---%<---
Size of SHORT_FLOAT =  32
Maximum relative error of COS =  2.38419E-07
Angle threshold =  12
X = 4294967296.00000; COS(X) =  1.00000      <-- WHAT?
--->%---

The corresponding C program:

---%<---
#include <math.h>
#include <stdio.h>

int main() {

   float x = exp2f(32.0);

   printf("sizeof(float) = %lu\n", sizeof(float));
   printf("x = %f; cos(x) = %f\n", x, cosf(x));

   return 0;
}
--->%---

gives:

---%<---
sizeof(float) = 4
x = 4294967296.000000; cos(x) = -0.886887    <--- OK
--->%---

Now, why is the error on cos(2**32) so large in this case? I am aware that I'm 
way beyond the required angle threshold mentioned in G.2.4(12), so it's up to 
the compiler to decide on the accuracy.

Looking at the implementation defined characteristics for GNAT, I find that 
strict mode is on by default, so G.2.4 should apply. For G.2.4(10) the 
documentation states (for the value of the angle threshold and the accuracy 
beyond the threshold): "Information on this subject is not yet available.".

So in principle the compiler is free to give me any answer once I'm beyond the 
minimum required angle threshold, which is about 12 for short float.

But if I understand G.2.4(10) correctly, cos(x1, cycle=>2*PI) should give me 
an answer within the maximum relative error, but this is not the case either, 
as EF.COS (X, CYCLE => TWO_PI) gives 0.33575.

Now for the questions: Is my reasoning above correct? Why does using the cycle 
parameter not help? Do other Ada compilers give the same bad result in this 
case? Should I report this as an error to AdaCore?

TIA,
Markus

^ permalink raw reply	[relevance 9%]

* Re: Ada.Numerics.Float_Random.Generator question
  2016-10-01 15:49  6%               ` Dmitry A. Kazakov
@ 2016-10-01 16:44  5%                 ` Robert Eachus
  0 siblings, 0 replies; 200+ results
From: Robert Eachus @ 2016-10-01 16:44 UTC (permalink / raw)


On Saturday, October 1, 2016 at 11:50:04 AM UTC-4, Dmitry A. Kazakov wrote:
> On 2016-10-01 16:23, Robert Eachus wrote:
> 
> > But there is infinite state, and infinite state. An infinite state
> > that is a simple counter of the number of values returned is probably
> > acceptable, a generator that requires storing the whole sequence is not.
> 
> There is no difference both are infinite. Single infinite counter is 
> capable to store whole sequence and conversely.

My point was that a state which slowly grows toward infinity (the counter) can easily be stored.  Any state that requires infinite storage or grows non-polynomially is right out.  States which grow by some polynomial in the counter?  Depends. 

On the issue of multiple seeds, Pi times an integer is also trancendental, but the values would be correlated between sequences.  Multiplying Pi by a rational number is better, but I think natural logs of primes would work.  Of course, now we have the problem of converting the seed selected by the programmer, or the clock, or whatever, into unique prime seeds.


^ permalink raw reply	[relevance 5%]

* Re: Ada.Numerics.Float_Random.Generator question
  2016-10-01 14:23  4%             ` Robert Eachus
@ 2016-10-01 15:49  6%               ` Dmitry A. Kazakov
  2016-10-01 16:44  5%                 ` Robert Eachus
  0 siblings, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2016-10-01 15:49 UTC (permalink / raw)


On 2016-10-01 16:23, Robert Eachus wrote:

> But there is infinite state, and infinite state. An infinite state
> that is a simple counter of the number of values returned is probably
> acceptable, a generator that requires storing the whole sequence is not.

There is no difference both are infinite. Single infinite counter is 
capable to store whole sequence and conversely.

> Of course, these are unbounded
> integers which will eventually require an array of finite integers to
> represent. (Multiprecision arithmetic) I think that is acceptable.

An unbounded array of integers is infinite. Once you have it bound, you 
get repeating states or else a program halt.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[relevance 6%]

* Re: Ada.Numerics.Float_Random.Generator question
  2016-10-01  3:59  6%           ` Paul Rubin
@ 2016-10-01 14:23  4%             ` Robert Eachus
  2016-10-01 15:49  6%               ` Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: Robert Eachus @ 2016-10-01 14:23 UTC (permalink / raw)


On Friday, September 30, 2016 at 11:59:15 PM UTC-4, Paul Rubin wrote:
> Robert Eachus <rieachus@comcast.net> writes:
> >> aren't *all* PRNGs cyclic?
> > No, a simple counter-example is a generator that uses the digits of
> > pi.  The digits of any transcendental number will do. 
> 
> I don't see how this would work--to never cycle, it would need infinite
> internal state.  You could consider the digits of pi to be part of the
> state, but to count off the digits, you need a counter of infinite
> width.

A quick proof that a PRNG that never cycles requires infinite state:  If the generator ever returns to a previous state?  It cycles.

But there is infinite state, and infinite state.  An infinite state that is a simple counter of the number of values returned is probably acceptable, a generator that requires storing the whole sequence is not.  (Hmm.  The generators in http://www.cs.ox.ac.uk/people/jeremy.gibbons/publications/spigot.pdf for Pi have a state of k integers for some k.  Of course, these are unbounded integers which will eventually require an array of finite integers to represent.  (Multiprecision arithmetic)  I think that is acceptable.

However, there is another problem with using the digits (binary, decimal, or hexadecimal) of Pi.  There is only one such sequence, so every program that uses it should start where other programs (in particular reruns of the same simulation) left off.  Choosing an n, then calulating ln n or e^n provides a seed that can be different for each run.

Is this discussion more than just idle chatter?  I think so.  Some of the spigot algorithms Paul Rubin points to are practical, given the speed of machines today.  Even if they are not quite, you can use a transcendental PRNG to seed a very long period non-trancendental generator every k values. Also more practical, if you are running a simulation on thousands of CPU cores, you can use a trancendental PRNG to seed each CPUs PRNG, or better reseed every n steps of the simulation.  (Note that you do not need to distribute the new seeds, they can be generated locally.  Again, a trancendental generator with a parameter or parameters is the next thing to look for. ;-)

^ permalink raw reply	[relevance 4%]

* Re: Ada.Numerics.Float_Random.Generator question
  2016-10-01  3:35  6%         ` Robert Eachus
@ 2016-10-01  3:59  6%           ` Paul Rubin
  2016-10-01 14:23  4%             ` Robert Eachus
  0 siblings, 1 reply; 200+ results
From: Paul Rubin @ 2016-10-01  3:59 UTC (permalink / raw)


Robert Eachus <rieachus@comcast.net> writes:
>> aren't *all* PRNGs cyclic?
> No, a simple counter-example is a generator that uses the digits of
> pi.  The digits of any transcendental number will do. 

I don't see how this would work--to never cycle, it would need infinite
internal state.  You could consider the digits of pi to be part of the
state, but to count off the digits, you need a counter of infinite
width.

> But about how to implement it so that you don't have arbitrary pauses.

https://en.wikipedia.org/wiki/Spigot_algorithm


^ permalink raw reply	[relevance 6%]

* Re: Ada.Numerics.Float_Random.Generator question
  2016-09-29  9:42  6%       ` Some Dude
@ 2016-10-01  3:35  6%         ` Robert Eachus
  2016-10-01  3:59  6%           ` Paul Rubin
  0 siblings, 1 reply; 200+ results
From: Robert Eachus @ 2016-10-01  3:35 UTC (permalink / raw)


On Thursday, September 29, 2016 at 5:42:17 AM UTC-4, Some Dude wrote:
> To add to Bruce's comment, aren't *all* PRNGs cyclic? I was always under this impression, but admittedly never looked for a proof.

No, a simple counter-example is a generator that uses the digits of pi.  The digits of any transcendental number will do. I'll have to think about generator based on a square root. (Not about whether it would work, it would.  But about how to implement it so that you don't have arbitrary pauses.  Hmm.  One task to generate the root?  Managing priorities could be tricky.)

^ permalink raw reply	[relevance 6%]

* Re: Ada.Numerics.Float_Random.Generator question
  2016-09-26 18:48  5%     ` brbarkstrom
@ 2016-09-29  9:42  6%       ` Some Dude
  2016-10-01  3:35  6%         ` Robert Eachus
  0 siblings, 1 reply; 200+ results
From: Some Dude @ 2016-09-29  9:42 UTC (permalink / raw)


To add to Bruce's comment, aren't *all* PRNGs cyclic? I was always under this impression, but admittedly never looked for a proof.


^ permalink raw reply	[relevance 6%]

* Re: Ada.Numerics.Float_Random.Generator question
  2016-09-26 13:04  5%   ` Robert Eachus
@ 2016-09-26 18:48  5%     ` brbarkstrom
  2016-09-29  9:42  6%       ` Some Dude
  0 siblings, 1 reply; 200+ results
From: brbarkstrom @ 2016-09-26 18:48 UTC (permalink / raw)


On Monday, September 26, 2016 at 9:04:34 AM UTC-4, Robert Eachus wrote:
> > 
> > > I hope that there is a better solution to this.  Is there?
> > 
> > Probably best consult Knuth on Random Numbers.  Complicated subject; lots
> > of numerical issues - testing involves some high-powered math.  See also
> > Park and Miller in CACM back a fer decades ago.
>  
> Sigh! I'm probably not the best expert available on random numbers (and pseudo RNGs).  But I could write a book on the inadequacies of Park and Miller, or all that has been learned since Knuth.  It is now possible to have fast PRNGs based on Blum, Blum, and Schub (https://en.wikipedia.org/wiki/Blum_Blum_Shub ) and that is now thirty year old technology. The latest includes not only cryptographically secure RNGs, but quantum cryptography which allows for seeds to be communicated without risk of evesdropping.
> 
> Most of that is more than needed for most RNGs, but there is no reason not to be at least that good. Park and Miller for example will "roll over" and start generating the same sequence again.  When it was publish this was not a big risk.  Today even "small" simulations will use more values that Park and Miller should be used to generate.
> 
> Oh, and I should probably write up a paper on using RNGs correctly.  It is silly to use an RNG that has lots of (theoretical) nice properties, then throw all that away in how you use the RNG.

Of course most of the RNG's roll over.  That's been known - and is even
referenced in Knuth.  The key question is selecting the appropriate values
for the algorithm so you can get longer cycles.  I know Park was
moving toward running multiple RNGs and then selecting one of them 
(approximately at random), but that was a long time ago.  

The National Institute for Standards and Technology (NIST) has probably
included RNG's in a note:
https://www.nist.gov/news-events/news/2014/04/nist-removes-cryptography-algorithm-random-number-generator-recommendations.  http://www.colostate.edu/~pburns/monte/rngreport.pdf doesn't have references after 2000.  The most
recent URL I could find in Wikipedia was https://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator, which has
an update from Sept. 1, 2016.

Probably the place to start is the NIST URL: http://csrc.nist.gov/groups/ST/toolkit/random_number.html and then consult the last major entry on
that page for the NIST approved algorithms and their suggested validation
algorithms that include recommended statistical tests.

Bruce B.


^ permalink raw reply	[relevance 5%]

* Re: Ada.Numerics.Float_Random.Generator question
  2016-09-25 23:41  6% ` brbarkstrom
@ 2016-09-26 13:04  5%   ` Robert Eachus
  2016-09-26 18:48  5%     ` brbarkstrom
  0 siblings, 1 reply; 200+ results
From: Robert Eachus @ 2016-09-26 13:04 UTC (permalink / raw)


On Sunday, September 25, 2016 at 7:41:26 PM UTC-4, brbar...@gmail.com wrote:
> 
> > I hope that there is a better solution to this.  Is there?
> 
> Probably best consult Knuth on Random Numbers.  Complicated subject; lots
> of numerical issues - testing involves some high-powered math.  See also
> Park and Miller in CACM back a fer decades ago.
 
Sigh! I'm probably not the best expert available on random numbers (and pseudo RNGs).  But I could write a book on the inadequacies of Park and Miller, or all that has been learned since Knuth.  It is now possible to have fast PRNGs based on Blum, Blum, and Schub (https://en.wikipedia.org/wiki/Blum_Blum_Shub ) and that is now thirty year old technology. The latest includes not only cryptographically secure RNGs, but quantum cryptography which allows for seeds to be communicated without risk of evesdropping.

Most of that is more than needed for most RNGs, but there is no reason not to be at least that good. Park and Miller for example will "roll over" and start generating the same sequence again.  When it was publish this was not a big risk.  Today even "small" simulations will use more values that Park and Miller should be used to generate.

Oh, and I should probably write up a paper on using RNGs correctly.  It is silly to use an RNG that has lots of (theoretical) nice properties, then throw all that away in how you use the RNG. 


^ permalink raw reply	[relevance 5%]

* Re: Ada.Numerics.Float_Random.Generator question
  2016-09-17 19:40 13% Ada.Numerics.Float_Random.Generator question Andrew Shvets
                   ` (2 preceding siblings ...)
  2016-09-19 19:07 10% ` rieachus
@ 2016-09-25 23:41  6% ` brbarkstrom
  2016-09-26 13:04  5%   ` Robert Eachus
  3 siblings, 1 reply; 200+ results
From: brbarkstrom @ 2016-09-25 23:41 UTC (permalink / raw)


On Saturday, September 17, 2016 at 3:40:13 PM UTC-4, Andrew Shvets wrote:
> Hello,
> 
> If I want a random float number to be generated, the way that I did this in the past was something along these lines:
> 
>   function Create_Random_Float(
>     From : in Float;
>     To : in Float)
>       return Float is
> 
>     Seed : Ada.Numerics.Float_Random.Generator;
>   begin
>     Ada.Numerics.Float_Random.Reset(Seed);
> 
>     return From + (Ada.Numerics.Float_Random.Random(Seed) * To);
>   end Create_Random_Float;
> 
> This works.  However, as I'm now looking into the Ada.Numerics.Discrete_Random package, I've noticed that it can generate a random value based on the type that is passed in.  This appeals to me and I'd like to do the same for a custom float type (say I want the delta to be 0.01.)
> 
> As Ada.Numerics.Float_Random.Generator is not a generic package, I can't use the same approach.  The best way that I can think of is to create the same result using From and To and then cast the result to the custom float type.
> 
> I hope that there is a better solution to this.  Is there?

Probably best consult Knuth on Random Numbers.  Complicated subject; lots
of numerical issues - testing involves some high-powered math.  See also
Park and Miller in CACM back a fer decades ago.

Bruce B.

^ permalink raw reply	[relevance 6%]

* Re: Ada.Numerics.Float_Random.Generator question
  2016-09-17 19:40 13% Ada.Numerics.Float_Random.Generator question Andrew Shvets
  2016-09-17 20:09  5% ` J-P. Rosen
  2016-09-17 21:01 10% ` Jeffrey R. Carter
@ 2016-09-19 19:07 10% ` rieachus
  2016-09-25 23:41  6% ` brbarkstrom
  3 siblings, 0 replies; 200+ results
From: rieachus @ 2016-09-19 19:07 UTC (permalink / raw)


On Saturday, September 17, 2016 at 3:40:13 PM UTC-4, Andrew Shvets wrote:
 
> This works.  However, as I'm now looking into the Ada.Numerics.Discrete_Random package, I've noticed that it can generate a random value based on the type that is passed in.  This appeals to me and I'd like to do the same for a custom float type (say I want the delta to be 0.01.)
> 
> As Ada.Numerics.Float_Random.Generator is not a generic package, I can't use the same approach.  The best way that I can think of is to create the same result using From and To and then cast the result to the custom float type.
> 
> I hope that there is a better solution to this.  Is there?

Since working has to be better, yes.  First, what you seem to be asking for is a PRNG that selects from a uniform distribution of fixed point values.  To do this take the generic discrete random package, and redeclare it with a fixed point type:

generic
   type Result_Subtype is delta <>;
package My_Fixed_Random is

   -- Basic facilities

   type Generator is limited private;

   function Random (Gen : Generator) return Result_Subtype;

   procedure Reset (Gen       : in Generator;
                    Initiator : in Integer);
   procedure Reset (Gen       : in Generator);

   -- Advanced facilities

   type State is private;

   procedure Save  (Gen        : in  Generator;
                    To_State   : out State);
   procedure Reset (Gen        : in  Generator;
                    From_State : in  State);

   Max_Image_Width : constant := implementation-defined integer value;

   function Image (Of_State    : State)  return String;
   function Value (Coded_State : String) return State;

private
   
end My_Fixed_Random;

Now in the body, put an instance of generic discrete random fit to your fixed point type:

package body My_Fixed_Random is
  type Hidden is range Int64(Result_Subtype'First/Result_Subtype'Small)     ..Int64(Result_Subtype'Last/Result_Subtype'Small);

  package Hidden_Pkg is new Ada.Numerics.Discrete_Random(Hidden);

  Complete with the operations from My_Fixed_Random, multiplying by 'Small and converting to Result_Subtype where needed. All done. ;-)  I wish I had gotten this package added to the Numerics section, as you can see it is about a page of very easy code.  But there were lots of other issues that needed resolving, and not enough time to resolve them all.

Now for the evils that I hope you never meet.  With this package, you should generate only numbers that are multiples of 'Small, and each legal value for Result_Subtype should occur with equal probability.  You might have an issue with a value next below 'First, but usually if you have a fixed point type that officially has 2^n - 1 values, you will know what to do to avoid Constraint_Error.  More troubling is that the language rules allow for fixed point types where the specified 'Small or 'Delta does not evenly divide one.  I do think that permission is right--but if you use it, you had better know a lot about numerics.

^ permalink raw reply	[relevance 10%]

* Re: Ada.Numerics.Float_Random.Generator question
  2016-09-17 21:01 10% ` Jeffrey R. Carter
@ 2016-09-17 23:53  6%   ` Andrew Shvets
  0 siblings, 0 replies; 200+ results
From: Andrew Shvets @ 2016-09-17 23:53 UTC (permalink / raw)


On Saturday, September 17, 2016 at 5:01:29 PM UTC-4, Jeffrey R. Carter wrote:
> On 09/17/2016 12:40 PM, Andrew Shvets wrote:
> > Hello,
> > 
> > If I want a random float number to be generated, the way that I did this in the past was something along these lines:
> > 
> >   function Create_Random_Float(
> >     From : in Float;
> >     To : in Float)
> >       return Float is
> > 
> >     Seed : Ada.Numerics.Float_Random.Generator;
> >   begin
> >     Ada.Numerics.Float_Random.Reset(Seed);
> > 
> >     return From + (Ada.Numerics.Float_Random.Random(Seed) * To);
> >   end Create_Random_Float;
> > 
> > This works.  
> 
> No, it doesn't. If From is 5 and To is 10, This gives a value in 5 .. 15.

You're right.

^ permalink raw reply	[relevance 6%]

* Re: Ada.Numerics.Float_Random.Generator question
  2016-09-17 19:40 13% Ada.Numerics.Float_Random.Generator question Andrew Shvets
  2016-09-17 20:09  5% ` J-P. Rosen
@ 2016-09-17 21:01 10% ` Jeffrey R. Carter
  2016-09-17 23:53  6%   ` Andrew Shvets
  2016-09-19 19:07 10% ` rieachus
  2016-09-25 23:41  6% ` brbarkstrom
  3 siblings, 1 reply; 200+ results
From: Jeffrey R. Carter @ 2016-09-17 21:01 UTC (permalink / raw)


On 09/17/2016 12:40 PM, Andrew Shvets wrote:
> Hello,
> 
> If I want a random float number to be generated, the way that I did this in the past was something along these lines:
> 
>   function Create_Random_Float(
>     From : in Float;
>     To : in Float)
>       return Float is
> 
>     Seed : Ada.Numerics.Float_Random.Generator;
>   begin
>     Ada.Numerics.Float_Random.Reset(Seed);
> 
>     return From + (Ada.Numerics.Float_Random.Random(Seed) * To);
>   end Create_Random_Float;
> 
> This works.  

No, it doesn't. If From is 5 and To is 10, This gives a value in 5 .. 15.

However, as I'm now looking into the Ada.Numerics.Discrete_Random package, I've
noticed that it can generate a random value based on the type that is passed in.
 This appeals to me and I'd like to do the same for a custom float type (say I
want the delta to be 0.01.)
> 
> As Ada.Numerics.Float_Random.Generator is not a generic package, I can't use the same approach.  The best way that I can think of is to create the same result using From and To and then cast the result to the custom float type.

The PragmAda Reusable Components contain several RNGs, all of which can be used
to obtain random values of user-defined floating-point types. You can find them at

https://github.com/jrcarter/PragmARC

-- 
Jeff Carter
"C++ is like jamming a helicopter inside a Miata
and expecting some sort of improvement."
Drew Olbrich
51

^ permalink raw reply	[relevance 10%]

* Re: Ada.Numerics.Float_Random.Generator question
  2016-09-17 20:09  5% ` J-P. Rosen
@ 2016-09-17 20:14 11%   ` Andrew Shvets
  0 siblings, 0 replies; 200+ results
From: Andrew Shvets @ 2016-09-17 20:14 UTC (permalink / raw)


On Saturday, September 17, 2016 at 4:10:03 PM UTC-4, J-P. Rosen wrote:
> Le 17/09/2016 à 21:40, Andrew Shvets a écrit :
> > This works.  However, as I'm now looking into the
> > Ada.Numerics.Discrete_Random package, I've noticed that it can
> > generate a random value based on the type that is passed in.  This
> > appeals to me and I'd like to do the same for a custom float type
> > (say I want the delta to be 0.01.)
> 
> Beware! Random number generators are tricky. It took megabytes of
> discussion to come to the conclusion that it was not possible to make a
> proper discrete generator out of a floating point generator...
> 
> Now, if you want a delta of 0.01, it looks more like a fixed point than
> a floating point. This can be easily achieved by instantiating
> discrete_random on an integer type with the proper number of values and
> then multiplying by 0.01.
> -- 
> J-P. Rosen
> Adalog
> 2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
> Tel: +33 1 45 29 21 52, Fax: +33 1 45 29 25 00
> http://www.adalog.fr

So, basically, there is no equally elegant solution for floats as there is for Ada.Numerics.Discrete_Random and integer types.

That's unfortunate.

^ permalink raw reply	[relevance 11%]

* Re: Ada.Numerics.Float_Random.Generator question
  2016-09-17 19:40 13% Ada.Numerics.Float_Random.Generator question Andrew Shvets
@ 2016-09-17 20:09  5% ` J-P. Rosen
  2016-09-17 20:14 11%   ` Andrew Shvets
  2016-09-17 21:01 10% ` Jeffrey R. Carter
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 200+ results
From: J-P. Rosen @ 2016-09-17 20:09 UTC (permalink / raw)


Le 17/09/2016 à 21:40, Andrew Shvets a écrit :
> This works.  However, as I'm now looking into the
> Ada.Numerics.Discrete_Random package, I've noticed that it can
> generate a random value based on the type that is passed in.  This
> appeals to me and I'd like to do the same for a custom float type
> (say I want the delta to be 0.01.)

Beware! Random number generators are tricky. It took megabytes of
discussion to come to the conclusion that it was not possible to make a
proper discrete generator out of a floating point generator...

Now, if you want a delta of 0.01, it looks more like a fixed point than
a floating point. This can be easily achieved by instantiating
discrete_random on an integer type with the proper number of values and
then multiplying by 0.01.
-- 
J-P. Rosen
Adalog
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52, Fax: +33 1 45 29 25 00
http://www.adalog.fr


^ permalink raw reply	[relevance 5%]

* Ada.Numerics.Float_Random.Generator question
@ 2016-09-17 19:40 13% Andrew Shvets
  2016-09-17 20:09  5% ` J-P. Rosen
                   ` (3 more replies)
  0 siblings, 4 replies; 200+ results
From: Andrew Shvets @ 2016-09-17 19:40 UTC (permalink / raw)


Hello,

If I want a random float number to be generated, the way that I did this in the past was something along these lines:

  function Create_Random_Float(
    From : in Float;
    To : in Float)
      return Float is

    Seed : Ada.Numerics.Float_Random.Generator;
  begin
    Ada.Numerics.Float_Random.Reset(Seed);

    return From + (Ada.Numerics.Float_Random.Random(Seed) * To);
  end Create_Random_Float;

This works.  However, as I'm now looking into the Ada.Numerics.Discrete_Random package, I've noticed that it can generate a random value based on the type that is passed in.  This appeals to me and I'd like to do the same for a custom float type (say I want the delta to be 0.01.)

As Ada.Numerics.Float_Random.Generator is not a generic package, I can't use the same approach.  The best way that I can think of is to create the same result using From and To and then cast the result to the custom float type.

I hope that there is a better solution to this.  Is there?


^ permalink raw reply	[relevance 13%]

* Re: New IEEE Language Popularity Ratings
  @ 2016-08-06 23:32  4%             ` G.B.
  0 siblings, 0 replies; 200+ results
From: G.B. @ 2016-08-06 23:32 UTC (permalink / raw)


On 06.08.16 22:59, brbarkstrom@gmail.com wrote:
> Along this line, is there documentation of which random number tests GNAT
> used for its generator?


In only a clerkish way, not in an experts way, I found the following
answer in GNAT's s-rannum.ads, to whose body the comments in GNAT GPL 2014's
Ada.Numerics.{Discrete,Float}_Rnadom are referring (in a-nu{di,fl}ra.ads):

--  The generator currently provided by this package has an extremely long
--  period (at least 2**19937-1), and passes the Big Crush test suite, with the
--  exception of the two linear complexity tests. Therefore, it is suitable
--  for simulations, but should not be used as a cryptographic pseudo-random
--  source without additional processing.



-- 
"HOTDOGS ARE NOT BOOKMARKS"
Springfield Elementary teaching staff


^ permalink raw reply	[relevance 4%]

* Re: Profiling Ada binaries
  2016-08-01 23:36  4%             ` Jeffrey R. Carter
@ 2016-08-02  7:00  5%               ` Markus Schöpflin
  0 siblings, 0 replies; 200+ results
From: Markus Schöpflin @ 2016-08-02  7:00 UTC (permalink / raw)


Am 02.08.2016 um 01:36 schrieb Jeffrey R. Carter:
> On 08/01/2016 03:40 PM, rieachus@comcast.net wrote:
>> On Tuesday, July 26, 2016 at 4:37:31 AM UTC-4, Markus Schöpflin wrote:
>>
>>> Even using the non-generic versions I have not been able to get the
>>> hardware built-ins. The best I can achieve for a call to e.g. cos(X)
>>> is:
>>
>>>   call    ada__numerics__long_elementary_functions__cos
>>
>> Again GNAT docs to the rescue: 15.1 Machine code insertions:
>
> I think the OP would benefit from knowing why this is necessary.
>
> If you look at the body of Ada.Numerics.Long_Elementary_Functions.Cos,
> you'll probably find a call to {something that calls} the built-in
> function.
>
> If you look at the requirements for the Cos function in Annex A and Annex G
> (if implemented, which it is for GNAT), you'll find a number of
> requirements for accuracy and special cases. If you look at the definition
> of the built-in function, you'll likely find that it doesn't meet all of
> those requirements. Any call to Cos has to involve wrapping a call to the
> built-in function in code to ensure those requirements are met, so you
> won't find a call to the built-in function in the generated code.

I am aware of that. I was trying to state that you don't get the hardware
built-ins in GNAT, despite the claim of the grandparent poster.

We rely on the guarantees given by the Ada LRM in this case. To make matter
worse (performance wise), we use

   type F is new Float range Float'Range;

as the base float type to make sure that we don't silently run into +/-INF or
other IEEE corner cases. This forces us to use the generic versions in
Ada.Numerics.Generic_Elementary_Functions.

We could of course try

   subtype F is Float range Float'Range;

and use the non-generic versions found in Numerics.Elementary_Functions, which
might be faster than their generic counterpart.

But although we are doing a lot of trigonometric calculations in our code, the
performance hot spots are usually not caused by floating point arithmetic, so
fortunately I don't have to worry about this too much.

> Even if the built-in function met all the requirements, the desire for the
> compiler to be portable will result in the call to the built-in being
> squirrelled away, not produced by the code generator.
>
> The general rule, "If you need specific machine code, use a machine-code
> insertion," applies here. Of course, the result is non-portable code, while
> the call to the language-defined library function is portable.

Actually I don't agree with you here. I don't see a reason why GNAT shouldn't 
be able to generate code which uses the built-in HW primitives, at least when 
using an appropriate optimization level and inlining. The resulting binary 
isn't portable anyway.

Markus

^ permalink raw reply	[relevance 5%]

* Re: Profiling Ada binaries
  @ 2016-08-01 23:36  4%             ` Jeffrey R. Carter
  2016-08-02  7:00  5%               ` Markus Schöpflin
  0 siblings, 1 reply; 200+ results
From: Jeffrey R. Carter @ 2016-08-01 23:36 UTC (permalink / raw)


On 08/01/2016 03:40 PM, rieachus@comcast.net wrote:
> On Tuesday, July 26, 2016 at 4:37:31 AM UTC-4, Markus Schöpflin wrote:
>  
> 
>> Even using the non-generic versions I have not been able to get the hardware 
>> built-ins. The best I can achieve for a call to e.g. cos(X) is: 
> 
>>         call    ada__numerics__long_elementary_functions__cos
> 
> Again GNAT docs to the rescue: 15.1 Machine code insertions:

I think the OP would benefit from knowing why this is necessary.

If you look at the body of Ada.Numerics.Long_Elementary_Functions.Cos, you'll
probably find a call to {something that calls} the built-in function.

If you look at the requirements for the Cos function in Annex A and Annex G (if
implemented, which it is for GNAT), you'll find a number of requirements for
accuracy and special cases. If you look at the definition of the built-in
function, you'll likely find that it doesn't meet all of those requirements. Any
call to Cos has to involve wrapping a call to the built-in function in code to
ensure those requirements are met, so you won't find a call to the built-in
function in the generated code.

Even if the built-in function met all the requirements, the desire for the
compiler to be portable will result in the call to the built-in being squirreled
away, not produced by the code generator.

The general rule, "If you need specific machine code, use a machine-code
insertion," applies here. Of course, the result is non-portable code, while the
call to the language-defined library function is portable.

-- 
Jeff Carter
"Hello! Smelly English K...niggets."
Monty Python & the Holy Grail
08


^ permalink raw reply	[relevance 4%]

* Re: Quick Sort in Rosetta Code
  @ 2016-02-10 10:16  5%   ` gautier_niouzes
  0 siblings, 0 replies; 200+ results
From: gautier_niouzes @ 2016-02-10 10:16 UTC (permalink / raw)


I did not dig too far into the fixing (the tricky thing is to avoid going out of range with indices) but here is, as an inspiration, a simplified case where the index type is integer, and this one is working (I've taken the C version to start with):

with Ada.Numerics.Float_Random; use Ada.Numerics.Float_Random;

--with Ada.Text_IO; use Ada.Text_IO;

procedure Qsort is

  type Item_array is array(Integer Range <>) of Float;

  procedure Quick_sort (a: in out Item_array) is
    n: Integer:= a'Length;
    i, j: Integer;
    p, t: Float;
  begin
    if n < 2 then
      return;
    end if;
    p := a(n / 2 + a'First);
    i:= 0;
    j:= n - 1;
    loop
      while a(i + a'First) < p loop
        i:= i + 1;
      end loop;
      while p < a(j + a'First) loop
        j:= j - 1;
      end loop;
      exit when i >= j;
      t := a(i + a'First);
      a(i + a'First) := a(j + a'First);
      a(j + a'First) := t;
      i:= i + 1;
      j:= j - 1;
    end loop;
    Quick_sort(a(a'First .. a'First + i - 1));
    Quick_sort(a(a'First + i .. a'Last));
  end;

  gen: Generator;

begin
  Reset(gen);
  for n in 1..100 loop
    for round in 1..500 loop
      declare
        start: Integer:= Integer(10.0 * (Random(gen)-0.5));
        a: Item_array(start .. start + n - 1);
      begin
        for i in a'Range loop
          a(i):= Random(gen);
        end loop;
        Quick_sort(a);
        for i in a'Range loop
          -- Put_Line(Float'Image(a(i)));
          if i > a'First and then a(i-1) > a(i) then
            raise Program_Error;  --  Buggy sorting
          end if;
        end loop;
      end;
    end loop;
  end loop;
end;
_________________________ 
Gautier's Ada programming 
http://sf.net/users/gdemont/ 

^ permalink raw reply	[relevance 5%]

* Re: Ada e-books
  2015-11-19 18:19  3%         ` Jeffrey R. Carter
@ 2015-11-19 19:44  0%           ` Serge Robyns
  0 siblings, 0 replies; 200+ results
From: Serge Robyns @ 2015-11-19 19:44 UTC (permalink / raw)


On Thursday, 19 November 2015 19:19:49 UTC+1, Jeffrey R. Carter  wrote:
> The Kindle app on Android tablets works well. I've heard that Calibre can
> convert AZW to EPUB, but unless you've done it before you probably won't want to
> buy a book
> 

Precisely!  If I buy it will take the paper version.  I do love paper books but e-books are convenient when you travel.

> The Rosen trick is used to gain write access to an in-mode parameter. It was
> needed pre-Ada 12 to simulate in-out mode parameters to functions; Ada 12 allows
> such parameters so it is not needed as much. An example is the Generator passed
> to a random-number function such as Ada.Numerics.Float_Random.Random, specified as
> 

And I thought I was also used to implement some kind of multiple inheritance with containers.  I'll open a new discussion with why I've been looking into it.

Thanks.

^ permalink raw reply	[relevance 0%]

* Re: Ada e-books
  @ 2015-11-19 18:19  3%         ` Jeffrey R. Carter
  2015-11-19 19:44  0%           ` Serge Robyns
  0 siblings, 1 reply; 200+ results
From: Jeffrey R. Carter @ 2015-11-19 18:19 UTC (permalink / raw)


On 11/19/2015 02:41 AM, Serge Robyns wrote:
> 
> I did indeed find the LRM e-book and this is why I've been asking for the
> 2012 AARM (I'll add 2A's to avoid confusion).  I'm interested in the
> annotated version in e-book format.  I want to try to read it as I've been
> facing a few issues, miscomprehension, etc. in the hope to understand better
> some 'particularities' and things like the Rosen trick and others.

The ARM and AARM are available at

http://www.ada-auth.org/arm.html

in HTML, PDF, and text versions. I'm not aware of any e-book versions of the
AARM. Most e-readers can display PDFs.

The title of the document is /Ada Reference Manual/, which is why many of us
refer to it as the ARM and interpret the A in ARM as "Ada". It's sometimes
referred to as the RM or LRM, which naturally lead to the questions, "RM for
what?" and "Which language?", which in this context are both answered, "Ada." So
yes, you need to say AARM here to refer to the Annotated ARM.

> I do agree with another post about the price of Programming in Ada 2012.
> However the Kindle format is reasonably priced, but then I don't have a
> Kindle.

The Kindle app on Android tablets works well. I've heard that Calibre can
convert AZW to EPUB, but unless you've done it before you probably won't want to
buy a book

The Rosen trick is used to gain write access to an in-mode parameter. It was
needed pre-Ada 12 to simulate in-out mode parameters to functions; Ada 12 allows
such parameters so it is not needed as much. An example is the Generator passed
to a random-number function such as Ada.Numerics.Float_Random.Random, specified as

function Random (Gen : Generator) return Uniformly_Distributed;

An example of its use can be found in pkg PragmARC.Threefry_Random:

   type Generator is tagged limited private;

   function Random (State : in Generator) return Unsigned_32;
...
   type Generator_Ptr is access all Generator;

   type Generator_Handle (State : Generator_Ptr) is limited null record;

   type Generator is new Ada.Finalization.Limited_Controlled with record
      Handle  : Generator_Handle (State => Generator'Unchecked_Access);
         -- The Rosen Trick
      Key     : Unsigned_256;
      State   : Unsigned_256;
      Output  : Unsigned_256;
      Counter : Natural;
   end record;

Write access to the State parameter of Random can be obtained though

      S : Generator renames State.Handle.State.all;

The PragmARCs are available at

https://pragmada.x10hosting.com/pragmarc.htm

PragmARC.Threefry_Random is only part of the version for ISO/IEC 8652:2007.

-- 
Jeff Carter
"Go and boil your bottoms."
Monty Python & the Holy Grail
01


^ permalink raw reply	[relevance 3%]

* Re: Generating a random number, not sure why I'm getting this error
  2015-11-16  2:29  4% ` Jeffrey R. Carter
@ 2015-11-16  2:53  0%   ` John Smith
  0 siblings, 0 replies; 200+ results
From: John Smith @ 2015-11-16  2:53 UTC (permalink / raw)


On Sunday, November 15, 2015 at 9:29:06 PM UTC-5, Jeffrey R. Carter wrote:
> On 11/15/2015 06:25 PM, John Smith wrote:
> > 
> > with Ada.Numerics.Discrete_Random; ... 
> > Ada.Numerics.Discrete_Random.Reset(Ada.Numerics.Discrete_Random.Generator);
> 
> Generator is a type, not something you can pass to a subprogram. What would you
> expect a call to Random to return?
> 
> > And this is the error that I get:
> > 
> > :13:15: invalid prefix in selected component "Ada.Numerics.Discrete_Random"
> > -- refers to the first Ada.Numerics.Discrete_Random...
> 
> Not a great error msg.
> 
> Discrete_Random is not a package: it's a generic package. You can consider a
> generic like a template for a package or subprogram. You create a package or
> subprogram from the generic through what Ada calls instantiation. When you
> instantiate Discrete_Random, you supply a discrete subtype to fill in for
> Result_Subtype; Random returns a value of this subtype.
> 
> So, for example,
> 
> package Random is new Ada.Numerics.Discrete_Random (Result_Subtype => Character;
> -- Random is the name of the pkg created by the instantiation
> 
> Gen : Random.Generator;
> C   : Character;
> 
> Random.Reset (Gen => Gen);
> C := Random.Random (Gen);
> 
> -- 
> Jeff Carter
> "Apart from the sanitation, the medicine, education, wine,
> public order, irrigation, roads, the fresh water system,
> and public health, what have the Romans ever done for us?"
> Monty Python's Life of Brian
> 80

Ok, that's what I was missing.  I didn't realize that that was how generic packages should be used.  I figured that they should be used just like any other package.

Thank you.

^ permalink raw reply	[relevance 0%]

* Re: Generating a random number, not sure why I'm getting this error
  2015-11-16  1:25  7% Generating a random number, not sure why I'm getting this error John Smith
@ 2015-11-16  2:29  4% ` Jeffrey R. Carter
  2015-11-16  2:53  0%   ` John Smith
  0 siblings, 1 reply; 200+ results
From: Jeffrey R. Carter @ 2015-11-16  2:29 UTC (permalink / raw)


On 11/15/2015 06:25 PM, John Smith wrote:
> 
> with Ada.Numerics.Discrete_Random; ... 
> Ada.Numerics.Discrete_Random.Reset(Ada.Numerics.Discrete_Random.Generator);

Generator is a type, not something you can pass to a subprogram. What would you
expect a call to Random to return?

> And this is the error that I get:
> 
> :13:15: invalid prefix in selected component "Ada.Numerics.Discrete_Random"
> -- refers to the first Ada.Numerics.Discrete_Random...

Not a great error msg.

Discrete_Random is not a package: it's a generic package. You can consider a
generic like a template for a package or subprogram. You create a package or
subprogram from the generic through what Ada calls instantiation. When you
instantiate Discrete_Random, you supply a discrete subtype to fill in for
Result_Subtype; Random returns a value of this subtype.

So, for example,

package Random is new Ada.Numerics.Discrete_Random (Result_Subtype => Character;
-- Random is the name of the pkg created by the instantiation

Gen : Random.Generator;
C   : Character;

Random.Reset (Gen => Gen);
C := Random.Random (Gen);

-- 
Jeff Carter
"Apart from the sanitation, the medicine, education, wine,
public order, irrigation, roads, the fresh water system,
and public health, what have the Romans ever done for us?"
Monty Python's Life of Brian
80

^ permalink raw reply	[relevance 4%]

* Generating a random number, not sure why I'm getting this error
@ 2015-11-16  1:25  7% John Smith
  2015-11-16  2:29  4% ` Jeffrey R. Carter
  0 siblings, 1 reply; 200+ results
From: John Smith @ 2015-11-16  1:25 UTC (permalink / raw)


Hello,

I don't understand why this is failing to compile.  I don't understand the rationale for the failure above all else:

with Ada.Numerics.Discrete_Random;
...
Ada.Numerics.Discrete_Random.Reset(Ada.Numerics.Discrete_Random.Generator);

And this is the error that I get:
:13:15: invalid prefix in selected component "Ada.Numerics.Discrete_Random" -- refers to the first Ada.Numerics.Discrete_Random...

The Ada documentation says that Discrete_Random has a Reset function, so why the error?
https://www2.adacore.com/gap-static/GNAT_Book/html/aarm/AA-A-5-2.html

I think I'm grossly misunderstanding how I'm calling Ada functions inside of packages.


^ permalink raw reply	[relevance 7%]

* Re: Understanding generic package functions
  2015-11-03  7:59  4%   ` Nick Gordon
  2015-11-03  9:15  5%     ` briot.emmanuel
@ 2015-11-03 17:27  0%     ` Jeffrey R. Carter
  1 sibling, 0 replies; 200+ results
From: Jeffrey R. Carter @ 2015-11-03 17:27 UTC (permalink / raw)


On 11/03/2015 12:59 AM, Nick Gordon wrote:
> 
> Oh! I see! Suddenly this makes much more sense. I appreciate this a lot! I
> see that it wasn't the declaration of Ada.Numerics.e that was the issue, but
> the generic package. How though do I use the overridden binary operator ** in
> that case? Do I call X MyPack."**" Y or is there some way for me to inform
> the compiler do it, like use MyPack;?

You have a number of options.

1. Full dotted name. An operator is a function just like any other function, and
can be called just like any other function:

Math."**" (X, Y)

2. Renaming.

function "**" (Left : Float; Right : Float) return Float renames Math."**";

This lets you use "**" as an infix operator: X ** Y

3. A use clause.

use Math;

This also lets you use "**" as an infix operator: X ** Y

The use clause gives you direct visibility to everything in the public part of
the pkg spec. Sometimes that's not desirable. I tend to avoid use clauses, since
they often make code harder to understand. I won't object too much for pkgs in
the standard library or for a limited scope with lots of references.

Not applicable in this case, but when a package declares a type and operations
on the type, you can use a "use type" clause

use [all] type Package_Name.Type_Name;

This gives direct visibility to the operators for Type_Name but not for anything
else in the pkg. If "all" is included, it makes some other things directly
visible, too, of which enumeration literals are the most commonly used.

-- 
Jeff Carter
"Drown in a vat of whiskey. Death, where is thy sting?"
Never Give a Sucker an Even Break
106

^ permalink raw reply	[relevance 0%]

* Re: Understanding generic package functions
    2015-11-03  6:59  5% ` Randy Brukardt
@ 2015-11-03  9:40  7% ` Stephen Leake
  1 sibling, 0 replies; 200+ results
From: Stephen Leake @ 2015-11-03  9:40 UTC (permalink / raw)


Nick Gordon <annihilan@gmail.com> writes:

> Okay, basically I'm writing a demo of Ada for a class, and I'm trying
> to showcase Ada's math functions. 

Is this a class on Ada, or something else?

> This is the code:
>
>    function Recoded_Exp(Power: in Float) return Float is -- Base e
>       use Ada.Numerics.Generic_Elementary_Functions;
>       use Ada.Numerics;
>       ExpResult : Float;
>    begin
>       ExpResult := e ** Power;
>       return ExpResult;
>    end Recoded_Exp;

Style notes: it's best not to use "use" unless it really cleans up the
code (my rule is "unless the name is used at least three times"), and
not to define a local variable unless it is really needed.

> I've seen something that suggests I have to instantiate the generic
> package, but I don't understand how.

This is how:

with Ada.Numerics.Generic_Elementary_Functions;
function Recoded_Exp(Power: in Float) return Float is -- Base e
   package Float_Elementary is new Ada.Numerics.Generic_Elementary_Functions
     (Float_Type => Float);
   use Float_Elementary;
begin
   return Ada.Numerics.e ** Power;
end Recoded_Exp;

"Instantiating a generic package" means declaring a package using a
generic template instead of providing all the code directly. So this
line:

   package Float_Elementary is new Ada.Numerics.Generic_Elementary_Functions
     (Float_Type => Float);

declares the package "Float_Elementary", using the code from
Generic_Elementary_Functions, with "Float_Type" replaced by "Float".

-- 
-- Stephe

^ permalink raw reply	[relevance 7%]

* Re: Understanding generic package functions
  2015-11-03  7:59  4%   ` Nick Gordon
@ 2015-11-03  9:15  5%     ` briot.emmanuel
  2015-11-03 17:27  0%     ` Jeffrey R. Carter
  1 sibling, 0 replies; 200+ results
From: briot.emmanuel @ 2015-11-03  9:15 UTC (permalink / raw)



One you have instantiated the Math package, as suggested by Jeffrey, you need to add a "use" clause for it:

    use Math;

At this point, "**" becomes visible. Your use clause on Ada.Numerics does not play that role.

^ permalink raw reply	[relevance 5%]

* Re: Understanding generic package functions
  2015-11-03  6:59  5% ` Randy Brukardt
@ 2015-11-03  7:59  4%   ` Nick Gordon
  2015-11-03  9:15  5%     ` briot.emmanuel
  2015-11-03 17:27  0%     ` Jeffrey R. Carter
  0 siblings, 2 replies; 200+ results
From: Nick Gordon @ 2015-11-03  7:59 UTC (permalink / raw)


On Monday, November 2, 2015 at 9:36:45 PM UTC-6, Jeffrey R. Carter wrote:
> On 11/02/2015 05:45 PM, Nick Gordon wrote:
> > 
> > My thought is that I have to create a new instance of the
> > Generic_Elementary_Functions package, but I'm not sure if that's correct, or
> > how to do that. In general, I'm noticing that the learning curve for Ada is
> > steep, and there are not terribly many "quick references" for the language.
> 
> Generics exist for reuse. For example, Ada.Numerics.Generic_Elementary_Functions
> allows the reuse of its algorithms with numerous floating-point types. You
> create an instance of the generic package for a specific floating-point types
> through the process of instantiation. You can think of a generic as a template
> and instantiation in terms of macro expansion; you end up with a package with
> the name of the instantiation and every occurrence of the generic formal
> parameters replaced with the corresponding actual parameters from the
> instantiation. (This isn't exactly correct but is close enough for most people,
> especially for a beginner.) For example:
> 
> package Math is new Ada.Numerics.Generic_Elementary_Functions
>    (Float_Type => Float);
> 
> Now you have a package named Math with functions that operate on type Float:
> 
> F : Float := Math.Sqrt (Ada.Numerics.e);
> 
> If you define your own floating-point type
> 
> type Big is digits System.Max_Digits;
> 
> you can instantiate Generic_Elementary_Functions for it, too
> 
> package Big_Math is new Ada.Numerics.Generic_Elementary_Functions
> (Float_Type => Big);
> 
> -- 
> Jeff Carter
> "[T]he [Agile] idea that it's bad to spend an
> appropriate time at the beginning of the project
> to clarify the overall requirements and design
> is nonsense."
> Bertrand Meyer
> 149

Oh! I see! Suddenly this makes much more sense. I appreciate this a lot! I see that it wasn't the declaration of Ada.Numerics.e that was the issue, but the generic package. How though do I use the overridden binary operator ** in that case? Do I call X MyPack."**" Y or is there some way for me to inform the compiler do it, like use MyPack;?

On Tuesday, November 3, 2015 at 12:59:35 AM UTC-6, Randy Brukardt wrote:
> "Nick Gordon" <annihilan@gmail.com> wrote in message 
> news:cb181260-a5d3-4b5b-9a40-c925f7100b93@googlegroups.com...
> ...
> > My thought is that I have to create a new instance of the 
> > Generic_Elementary_Functions
> > package, but I'm not sure if that's correct, or how to do that.
> 
> Jeff gave you the long answer, which is better for most purposes. 
> Specifically for type Float (which you really should avoid itself, 
> preferring to use types of your own definition), Ada offers a 
> pre-instantiated version of the package called 
> "Ada.Numerics.Elementary_Functions", so you could use that instead.
> 
> > In general, I'm noticing that the learning curve for Ada is steep, and 
> > there are not
> > terribly many "quick references" for the language.
> 
> Ada Distilled is the best "quick reference", but there's really nothing 
> quick about using Ada. It's a professional level tool and thus it has lots 
> of things that you need to know. (Consider the difference between using a 
> home copy machine and a professional offset printing press.)
> 
>                                    Randy.

For better or worse, I've just ordered for $10 total two of the books listed in the adaic.org's "learning resources" section, so I'm hoping that they will be a better learning tool than Ada Distilled, which I already have. Again, thanks to the both of you.

Nick

^ permalink raw reply	[relevance 4%]

* Re: Understanding generic package functions
  @ 2015-11-03  6:59  5% ` Randy Brukardt
  2015-11-03  7:59  4%   ` Nick Gordon
  2015-11-03  9:40  7% ` Stephen Leake
  1 sibling, 1 reply; 200+ results
From: Randy Brukardt @ 2015-11-03  6:59 UTC (permalink / raw)



"Nick Gordon" <annihilan@gmail.com> wrote in message 
news:cb181260-a5d3-4b5b-9a40-c925f7100b93@googlegroups.com...
...
> My thought is that I have to create a new instance of the 
> Generic_Elementary_Functions
> package, but I'm not sure if that's correct, or how to do that.

Jeff gave you the long answer, which is better for most purposes. 
Specifically for type Float (which you really should avoid itself, 
preferring to use types of your own definition), Ada offers a 
pre-instantiated version of the package called 
"Ada.Numerics.Elementary_Functions", so you could use that instead.

> In general, I'm noticing that the learning curve for Ada is steep, and 
> there are not
> terribly many "quick references" for the language.

Ada Distilled is the best "quick reference", but there's really nothing 
quick about using Ada. It's a professional level tool and thus it has lots 
of things that you need to know. (Consider the difference between using a 
home copy machine and a professional offset printing press.)

                                   Randy.



^ permalink raw reply	[relevance 5%]

Results 1-200 of ~1100   | reverse | options above
-- pct% links below jump to the message on this page, permalinks otherwise --
2015-11-03  0:45     Understanding generic package functions Nick Gordon
2015-11-03  6:59  5% ` Randy Brukardt
2015-11-03  7:59  4%   ` Nick Gordon
2015-11-03  9:15  5%     ` briot.emmanuel
2015-11-03 17:27  0%     ` Jeffrey R. Carter
2015-11-03  9:40  7% ` Stephen Leake
2015-11-16  1:25  7% Generating a random number, not sure why I'm getting this error John Smith
2015-11-16  2:29  4% ` Jeffrey R. Carter
2015-11-16  2:53  0%   ` John Smith
2015-11-17 22:55     Ada e-books Serge Robyns
2015-11-17 23:01     ` Paul Rubin
2015-11-18  8:29       ` Serge Robyns
2015-11-18 12:14         ` Dirk Craeynest
2015-11-19  9:41           ` Serge Robyns
2015-11-19 18:19  3%         ` Jeffrey R. Carter
2015-11-19 19:44  0%           ` Serge Robyns
2016-02-10  5:27     Quick Sort in Rosetta Code gautier_niouzes
2016-02-10  7:14     ` Leo Brewin
2016-02-10 10:16  5%   ` gautier_niouzes
2016-07-22 13:24     Profiling Ada binaries Markus Schöpflin
2016-07-22 14:59     ` Alejandro R. Mosteo
2016-07-22 15:05       ` Alejandro R. Mosteo
2016-07-25  7:01         ` Markus Schöpflin
2016-07-25 16:45           ` rieachus
2016-07-26  8:37             ` Markus Schöpflin
2016-08-01 22:40               ` rieachus
2016-08-01 23:36  4%             ` Jeffrey R. Carter
2016-08-02  7:00  5%               ` Markus Schöpflin
2016-07-28 14:58     New IEEE Language Popularity Ratings brbarkstrom
2016-07-29  6:41     ` Jerry
2016-07-29 12:37       ` brbarkstrom
2016-08-03 15:24         ` Serge Robyns
2016-08-06 15:53           ` brbarkstrom
2016-08-06 20:10             ` rieachus
2016-08-06 20:59               ` brbarkstrom
2016-08-06 23:32  4%             ` G.B.
2016-09-17 19:40 13% Ada.Numerics.Float_Random.Generator question Andrew Shvets
2016-09-17 20:09  5% ` J-P. Rosen
2016-09-17 20:14 11%   ` Andrew Shvets
2016-09-17 21:01 10% ` Jeffrey R. Carter
2016-09-17 23:53  6%   ` Andrew Shvets
2016-09-19 19:07 10% ` rieachus
2016-09-25 23:41  6% ` brbarkstrom
2016-09-26 13:04  5%   ` Robert Eachus
2016-09-26 18:48  5%     ` brbarkstrom
2016-09-29  9:42  6%       ` Some Dude
2016-10-01  3:35  6%         ` Robert Eachus
2016-10-01  3:59  6%           ` Paul Rubin
2016-10-01 14:23  4%             ` Robert Eachus
2016-10-01 15:49  6%               ` Dmitry A. Kazakov
2016-10-01 16:44  5%                 ` Robert Eachus
2016-10-07 10:13  9% Ada.Numerics, Accuracy of trigonometric functions Markus Schöpflin
2016-10-07 10:23  6% ` Markus Schöpflin
2016-10-07 10:23  6% ` Brian Drummond
2016-10-07 10:40  6%   ` Markus Schöpflin
2016-10-07 14:52  5% ` Dennis Lee Bieber
2016-10-07 15:19  6%   ` Markus Schöpflin
2016-10-07 22:15  6%     ` Dennis Lee Bieber
2016-10-07 16:38 10% ` Jeffrey R. Carter
2016-10-10  7:44  6%   ` Markus Schöpflin
2016-10-22 22:38  9% ` Robert Eachus
2016-11-12 18:16     matrix manipulation hnptz
2016-11-12 23:30     ` Stephen Leake
2016-11-14 17:39       ` hnptz
2016-11-15 17:54  4%     ` Stephen Leake
2016-12-16  0:38     Trigonometric operations on x86 and x64 CPUs Robert Eachus
2016-12-16 20:50  5% ` Vadim Godunko
2017-01-02  2:42     Interfacing Ada With Full Runtime Directly to Electronic Chips patrick
2017-01-02 16:25  3% ` Simon Wright
2017-01-04 19:29  0%   ` antispam
2017-01-04 20:51  0%     ` Simon Wright
2017-01-04 22:05  0%       ` antispam
2017-01-22 11:37  6% Ok to assume type Duration is for more than one day? reinkor
2017-01-25 12:25 12% Ada.Numerics.Long_Real_Arrays hnptz
2017-01-25 13:50 11% ` Ada.Numerics.Long_Real_Arrays Simon Wright
2017-01-25 14:11  6% ` Ada.Numerics.Long_Real_Arrays hnptz
2017-01-25 16:17 13%   ` Ada.Numerics.Long_Real_Arrays Simon Wright
2017-01-25 18:35  6% ` Ada.Numerics.Long_Real_Arrays hnptz
2017-01-25 21:29  5% ` Ada.Numerics.Long_Real_Arrays hnptz
2017-01-26  7:47  6%   ` Ada.Numerics.Long_Real_Arrays Simon Wright
2017-01-26 11:54 12%     ` Ada.Numerics.Long_Real_Arrays hnptz
2017-01-26 14:52 10%       ` Ada.Numerics.Long_Real_Arrays Simon Wright
2017-01-26 15:03 13%         ` Ada.Numerics.Long_Real_Arrays Simon Wright
2017-01-26  7:49  6%   ` Ada.Numerics.Long_Real_Arrays Simon Wright
2017-01-26  7:55  6%     ` Ada.Numerics.Long_Real_Arrays Simon Wright
2017-01-27 16:51 11% ` Ada.Numerics.Long_Real_Arrays hnptz
2017-01-27 18:39 13%   ` Ada.Numerics.Long_Real_Arrays Simon Wright
2017-03-17 21:12     Interfaces.C questions hreba
2017-03-18 23:24     ` Leo Brewin
2017-03-19 12:17  4%   ` hreba
2017-03-20  9:44  0%     ` Leo Brewin
2017-03-19 18:39     ` hreba
2017-03-19 19:22       ` Simon Wright
2017-03-19 19:49         ` hreba
2017-03-19 23:53           ` Simon Wright
2017-03-20 14:04  4%         ` hreba
2017-03-22 11:21  0%           ` hreba
2017-03-23  7:43     Interfaces.C + generics: stack overflow hreba
2017-03-23 20:03     ` Randy Brukardt
2017-03-24 12:42  4%   ` hreba
2017-03-24 20:13  0%     ` Randy Brukardt
2017-03-29  1:29  4% Example Ada calling Gnu Scientific Library (GSL) Leo Brewin
2017-05-06  2:23     Portable memory barrier? Jere
2017-05-07 20:18     ` Robert Eachus
2017-05-08  7:45       ` Dmitry A. Kazakov
2017-05-08 15:56         ` Robert Eachus
2017-05-08 16:22           ` Dmitry A. Kazakov
2017-05-08 19:18             ` Robert Eachus
2017-05-08 21:09               ` Dmitry A. Kazakov
2017-05-08 23:24                 ` Robert Eachus
2017-05-09  0:30                   ` Jere
2017-05-09  4:32                     ` Robert Eachus
2017-05-09 22:26  4%                   ` Jere
2017-05-08 15:53     Question about sets and expression reinert
2017-05-08 19:00     ` Simon Wright
2017-05-09  3:58       ` reinert
2017-05-09  5:48  7%     ` reinert
2017-06-06 11:47     Arrays in Ada 2012 Anatoly Chernyshev
2017-06-18  2:14     ` Arrays in Ada 2020 Ivan Levashev
2017-06-18  3:00       ` Nasser M. Abbasi
2017-06-18 12:06  5%     ` Robert Eachus
2017-06-18 10:34     Help needed - "Storage_Error stack overflow or erroneous memory access" reinert
2017-06-18 10:41     ` Simon Clubley
2017-06-18 12:00       ` reinert
2017-06-18 12:24         ` Egil H H
2017-06-18 14:58           ` Simon Clubley
2017-06-18 15:44             ` reinert
2017-06-18 18:04               ` reinert
2017-06-19  4:53  5%             ` reinert
2017-06-30  1:15 12% Can't work out how to use with Ada.Numerics.Discrete_Random with SPARK 2014 digitig
2017-06-30  7:28  6% ` Simon Wright
2017-06-30 11:38 11%   ` digitig
2017-08-03  5:45     Community Input for the Maintenance and Revision of the Ada Programming Language Randy Brukardt
2017-08-28 23:49     ` faryumg
2017-09-02 10:49       ` Vincent DIEMUNSCH
2017-09-02 11:21         ` Johan Söderlind Åström
2017-09-03  1:30           ` Randy Brukardt
2017-09-06 15:02             ` Johan Söderlind Åström
2017-09-09 14:48  3%           ` G.B.
2017-08-08 13:04  4% ANN: Cortex GNAT RTS 2017-08-08 Simon Wright
2017-10-17  4:58  5% How to make tasks to run in parallel reinert
2017-10-17  6:17  5% ` Per Sandberg
2017-10-28 20:02  1% Read-write mutex sometimes fails on deadlock pascal.malaise
2017-11-24 11:42     How to access an array using two different indexing schemes Jerry
2017-11-24 17:37  6% ` A. Cervetti
2017-11-24 21:48  0%   ` Jerry
2017-11-24 22:15         ` Robert A Duff
2017-11-24 23:38  7%       ` Jerry
2017-11-26  1:07  0%         ` Jerry
2017-11-26  8:58  6%           ` Dmitry A. Kazakov
2017-11-26 10:31  0%             ` Jerry
2017-11-28  1:31  6%             ` Randy Brukardt
2017-11-28  1:25  0%   ` Randy Brukardt
2017-11-29  4:57         ` Jerry
2017-11-29 16:03           ` Shark8
2017-11-29 17:04             ` AdaMagica
2017-11-29 20:56               ` Randy Brukardt
2017-11-30  5:56                 ` Jerry
2017-11-30 21:50                   ` Randy Brukardt
2017-11-30 23:13  5%                 ` Jerry
2017-11-26  0:04     Instantiations of a generic with often encountered arguments Victor Porton
2017-11-26  8:52     ` Dmitry A. Kazakov
2017-11-27  2:02       ` Victor Porton
2017-11-27  8:00  7%     ` Simon Wright
2017-11-27 16:05  3%     ` Shark8
2018-01-28  7:48  4% Card game deck but with trumps suit for tarot "divination" Is there a better way than enumerating all cards? bozovic.bojan
2018-01-28  8:57  0% ` Jacob Sparre Andersen
2018-01-28  9:23  0%   ` bozovic.bojan
2018-02-03 11:06  5% Array of records with default values not propagating to array Bojan Bozovic
2018-02-03 14:16  4% ` Jere
2018-02-04  4:59  0% ` Bojan Bozovic
2018-02-04 10:19  0% ` Jeffrey R. Carter
2018-02-17 11:52  5% Generic_Rational hnptz
2018-02-17 12:33  0% ` Generic_Rational Simon Wright
2018-02-17 12:55  7% GNAT can't vectorize Real_Matrix multiplication from Ada.Numerics.Real_Arrays. What a surprise! Bojan Bozovic
2018-02-17 15:17  6% ` Bojan Bozovic
2018-02-17 15:49  6%   ` Bojan Bozovic
2018-02-18  1:51  9% ` Bojan Bozovic
2018-02-18 10:35 11%   ` Jeffrey R. Carter
2018-02-18 12:05  6%     ` Bojan Bozovic
2018-02-18 13:31 12%       ` Jeffrey R. Carter
2018-02-18 19:38  5%         ` Bojan Bozovic
2018-02-18 21:48  6%           ` Nasser M. Abbasi
2018-02-18 22:50 11%             ` Bojan Bozovic
2018-02-19 21:08  5%             ` Robert Eachus
2018-02-20  2:31  5%               ` Bojan Bozovic
2018-02-26  6:58  5%                 ` Robert Eachus
2018-02-25 12:30     64-bit unsigned integer? MM
2018-02-25 16:36     ` Anh Vo
2018-02-25 17:31       ` MM
2018-02-26 23:19         ` Randy Brukardt
2018-02-28 10:17           ` Paul Rubin
2018-02-28 23:20             ` Randy Brukardt
2018-03-01  5:47               ` Paul Rubin
2018-03-01  8:16                 ` Niklas Holsti
2018-03-01  8:35  5%               ` Simon Wright
2018-03-13 16:39     Mathpaqs release 13-Mar-2018 gautier_niouzes
2018-03-14 14:54     ` Vincent D.
2018-03-16 17:59  4%   ` gautier_niouzes
2018-04-06 13:22  7% Generic library design Marius Amado-Alves
2018-04-07  2:32  0% ` Randy Brukardt
2018-04-15 21:48     How to get Ada to “cross the chasm”? Dan'l Miller
2018-04-16  5:35     ` Paul Rubin
2018-04-18 13:29       ` Jere
2018-04-18 17:02         ` Lucretia
2018-05-04 13:30           ` Jere
2018-05-04 19:07             ` Niklas Holsti
2018-05-05  4:01               ` Dennis Lee Bieber
2018-05-05  8:06                 ` Simon Wright
2018-05-05 20:02                   ` Paul Rubin
2018-05-05 20:22                     ` Niklas Holsti
2018-05-05 23:06                       ` Paul Rubin
2018-05-06 16:58  6%                     ` Jacob Sparre Andersen
2018-05-26 21:03     why "unconstrained subtype in component declaration" while said component given default value ? Mehdi Saada
2018-05-26 21:40     ` Jere
2018-05-26 22:11  5%   ` Mehdi Saada
2018-05-26 23:55  0%     ` Jere
2018-05-27  0:14  0%       ` Jere
2018-05-29 19:41     Memory pools John Perry
2018-05-31 19:33  3% ` gorgelo
2018-07-16  8:20     Simple hash or pseudo-random function gautier_niouzes
2018-07-16 17:17  4% ` Jeffrey R. Carter
2018-07-16 21:14  0%   ` gautier_niouzes
2018-09-17  2:22  5% GNAT for AVR - Mathematical Functions ada.newcomer
2018-09-17 12:22  0% ` Simon Wright
2018-09-17 17:28  0% ` Bill Findlay
2018-09-25  7:14  0% ` R R
2018-11-21  9:56     overloading operators hnptz
2018-11-21 13:50  6% ` AdaMagica
2018-11-21 16:39  5%   ` hnptz
2018-11-21 17:37  5%     ` Simon Wright
2018-11-22  8:18  0%       ` briot.emmanuel
2018-11-22 11:39  0%         ` Simon Wright
2018-11-26 17:47  0%         ` Anh Vo
2018-11-26 18:03  0%           ` Simon Wright
2018-11-26 18:24  0%             ` Dmitry A. Kazakov
2019-01-24  3:59  8% basic question on Ada programming Nasser M. Abbasi
2019-01-24  7:58  6% ` Niklas Holsti
2019-04-01 16:28     Erfc() function in ADA leov
2019-04-02 10:39  4% ` gautier_niouzes
2019-04-03 16:01  0%   ` leov
2019-05-30 10:26  7% old problem Gilbert Gosseyn
2019-05-30 17:08  0% ` Anh Vo
2019-05-31  1:04  0% ` Keith Thompson
2019-05-31 12:37  7% ` Simon Wright
2019-07-22  4:38     The answer to "Can Ada replace FORTRAN for numerical computation? Nasser M. Abbasi
2019-07-23  1:35  6% ` Brad Moore
2020-03-23 23:16  5% GNAT vs Matlab - operation on multidimensional complex matrices darek
2020-06-08 17:42  6% ` Shark8
2020-05-31 10:46     Any good package for mathematical function in Ada? reinert
2020-05-31 23:25     ` Jerry
2020-06-01  8:24       ` reinert
2020-06-01 10:19         ` Dmitry A. Kazakov
2020-06-01 10:48           ` Nasser M. Abbasi
2020-06-01 11:34             ` Dmitry A. Kazakov
2020-06-05 22:54               ` Paul Rubin
2020-06-06  7:06                 ` Dmitry A. Kazakov
2020-06-06 13:58  7%               ` AdaMagica
2020-06-05 14:35     generic with function procedure Gilbert Gosseyn
2020-06-05 14:52  6% ` gautier_niouzes
2020-06-05 15:45  0%   ` Gilbert Gosseyn
2020-11-28  3:12     Advent of Code John Perry
2020-12-02 20:51     ` gautier...@hotmail.com
2020-12-02 21:29       ` Max Reznik
2020-12-02 23:04         ` Stephen Leake
2020-12-03 14:52           ` Wendel Wang
2020-12-03 17:20             ` Björn Lundin
2020-12-03 18:50               ` gautier...@hotmail.com
2020-12-03 19:47                 ` Björn Lundin
2020-12-08 20:44                   ` Max Reznik
2020-12-08 21:06                     ` John Perry
2020-12-13 18:26                       ` Maxim Reznik
2020-12-13 21:36  5%                     ` John Perry
2020-12-11  3:39     advent of code day 10 Stephen Leake
2020-12-11  5:40     ` Jared Summers
2020-12-11 17:04  5%   ` Stephen Leake
2021-03-14  1:32  6% Compiler stuck on Big_Integer array initialisation Jesper Quorning
2021-04-23  6:37  0% ` Simon Wright
2021-04-27 14:04     Constraint error overflow Richard Iswara
2021-04-27 15:00     ` Dmitry A. Kazakov
2021-04-27 15:32       ` Richard Iswara
2021-04-27 16:31  6%     ` Simon Wright
2021-07-20 12:02  7% Gnat bug or mistaken program? Richard Iswara
2021-07-20 14:09  6% ` Niklas Holsti
2021-07-21  2:23  0%   ` Richard Iswara
2021-07-21  8:29  5%     ` Jeffrey R. Carter
2021-07-21 16:56  0%       ` Shark8
2021-07-22  2:14  0%         ` Richard Iswara
2021-07-27 16:00  0%       ` Niklas Holsti
2021-07-28  5:21  0%         ` J-P. Rosen
2021-12-22  5:57 11% Ada.Numerics.Big_Numbers.Big_Integer has a limit of 300 digits? Michael Ferguson
2021-12-22  8:25  6% ` Mark Lorenzen
2021-12-22 11:14  6% ` AdaMagica
2021-12-22 11:32  6%   ` AdaMagica
2021-12-22 16:04  6%   ` AdaMagica
2021-12-22 17:37  5%     ` Niklas Holsti
2021-12-22 20:34  6%   ` Simon Wright
2021-12-22 17:01  6% ` Luke A. Guest
2021-12-22 17:27  5%   ` Michael Ferguson
2021-12-22 17:43  6%     ` Ben Bacarisse
2021-12-22 17:48 11%     ` Niklas Holsti
2021-12-22 18:02 10%       ` Michael Ferguson
2021-12-22 19:05  4%         ` Niklas Holsti
2021-12-23  8:31  6%           ` Luke A. Guest
2021-12-23  8:54  6%             ` Dmitry A. Kazakov
2021-12-23 11:41  6%           ` AdaMagica
2021-12-23 12:18  5%             ` Niklas Holsti
2021-12-23 14:01  6%               ` Ben Bacarisse
2021-12-22 19:26  6%     ` Mark Lorenzen
2021-12-22 20:43  6%       ` Niklas Holsti
2021-12-22 20:31  6%     ` Paul Rubin
2021-12-22 20:39  6%     ` Paul Rubin
2021-12-23 15:48  6% ` Jeffrey R.Carter
2021-12-24  9:09 13%   ` AdaMagica
2022-02-03 20:14  3% Ada Developer Room at FOSDEM 2022 - Sun 6 Feb - online Dirk Craeynest
2022-02-20 14:23  4% Ada Developer Room at FOSDEM 2022 - videos online Dirk Craeynest
2023-01-22 21:34     Real_Arrays on heap with overloaded operators and clean syntax Jim Paloander
2023-01-22 21:56     ` Joakim Strandberg
2023-01-22 22:07       ` Jim Paloander
2023-01-22 22:42         ` Joakim Strandberg
2023-01-22 22:49           ` Jim Paloander
2023-01-22 23:14  6%         ` Gautier write-only address
2023-01-23  1:14  6%           ` Leo Brewin
2023-01-23  6:01  0%             ` Jim Paloander
2023-06-30 19:28  7% GNAT Community 2020 (20200818-93): Big_Integer Frank Jørgen Jørgensen
2023-06-30 21:07  4% ` Dmitry A. Kazakov
2023-07-01 12:12     ` Simon Wright
2023-07-08  2:58  5%   ` Randy Brukardt
2023-07-27  5:26     When using the Ada Big_Numbers.Big_Integers package, can the To_String function output be sliced? Kenneth Wolcott
2023-07-27  8:53  6% ` Jeffrey R.Carter
2023-07-27 22:47  5%   ` Kenneth Wolcott
2023-07-28 18:21         ` Simon Wright
2023-07-29 11:07           ` AdaMagica
2023-07-29 23:49             ` Kenneth Wolcott
2023-07-29 23:53  6%           ` Kenneth Wolcott
2023-07-30  4:43  5%             ` Randy Brukardt
2023-09-15  9:03     project euler 29 CSYH (QAQ)
2023-09-15  9:50  5% ` Jeffrey R.Carter
2023-09-15 18:04  0%   ` Keith Thompson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox