* Re: Understanding generic package functions
2015-11-03 0:45 7% Understanding generic package functions Nick Gordon
@ 2015-11-03 3:36 7% ` Jeffrey R. Carter
0 siblings, 0 replies; 200+ results
From: Jeffrey R. Carter @ 2015-11-03 3:36 UTC (permalink / raw)
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
^ permalink raw reply [relevance 7%]
* Understanding generic package functions
@ 2015-11-03 0:45 7% Nick Gordon
2015-11-03 3:36 7% ` Jeffrey R. Carter
0 siblings, 1 reply; 200+ results
From: Nick Gordon @ 2015-11-03 0:45 UTC (permalink / raw)
Okay, basically I'm writing a demo of Ada for a class, and I'm trying to showcase Ada's math functions. 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;
As you can see, what I'm trying to accomplish is confine the Float version of the "**" operator to this function, and I can't seem to do that, as well as use Ada's language-defined e constant. I've tried this by declaring the whole name, i.e. "Ada.Numerics.e Ada.Numerics.Generic_Elementary_Functions."**" Power", as well without the quotes enclosing the asterisks. Neither worked.
I've seen something that suggests I have to instantiate the generic package, but I don't understand how. For reference, the suggested approach is here:
with Square;
with Matrices;
procedure Matrix_Example is
function Square_Matrix is new Square
(Element_T => Matrices.Matrix_T, "*" => Matrices.Product);
A : Matrices.Matrix_T := Matrices.Identity;
begin
A := Square_Matrix (A);
end Matrix_Example;
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.
Nick
^ permalink raw reply [relevance 7%]
* Re: If not Ada, what else...
@ 2015-07-30 10:59 5% ` darkestkhan
0 siblings, 0 replies; 200+ results
From: darkestkhan @ 2015-07-30 10:59 UTC (permalink / raw)
On Wednesday, July 29, 2015 at 12:38:43 PM UTC, EGarrulo wrote:
> Why wouldn't Ada be good for hacking? The only drawback I can see
> does not relate to the language itself, but to the lack of flexible
> standard libraries. For example, in an experiment comparing the
> productivity of some programming languages[1], and where Haskell
> comes way ahead of the pack, authors note that "[...] the Haskell
> prototype was most concise for three reasons: [...] (2) the use of
> higher-order functions, and (3) the use of standard list-manipulating
> primitives in the standard [library] Prelude." Ada supports higher-
> order functions, but it has nothing like the standard library Prelude
> in Haskell, or the STL in C++. And I find it ironic that Stepanov
> wrote the original version of the C++ STL in Ada, but then it never
> found its way into the Ada standard.
Check Annex A in Ada Reference Manual. You got Ada.Containers.* for standard containers, Ada.Strings.* for string handling (also Unbounded_Strings), Ada.Numerics.*, etc.
There are also Annexes C, D, F and G... (E is far too specific for distributed systems and usually not that much needed in day-to-day basis)
^ permalink raw reply [relevance 5%]
* Re: Error "exception not permitted here" when putting EXCEPTION in a loop
2015-07-18 14:32 4% ` Trish Cayetano
@ 2015-07-18 14:59 4% ` Björn Lundin
0 siblings, 0 replies; 200+ results
From: Björn Lundin @ 2015-07-18 14:59 UTC (permalink / raw)
On 2015-07-18 16:32, Trish Cayetano wrote:
> On Saturday, July 18, 2015 at 9:55:12 PM UTC+8, björn lundin wrote:
This one works.
As Tero said - skip_line in exception handler does it.
But you ONLY need it there.
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with Ada.Numerics.Discrete_Random;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Ada.Text_IO.Unbounded_IO; use Ada.Text_IO.Unbounded_IO;
with Ada.IO_Exceptions; use Ada.IO_Exceptions;
procedure Main is
GuessWord : String(1..20);
last: Natural;
option : Integer := 0;
endGame: Boolean := False;
begin
while not endGame loop
begin
Ada.Text_IO.Put_Line(" | CHOOSE YOUR OPTION: 1)Shuffle 2)Pass
3)Enter Word 4)Exit ");
Ada.Integer_Text_IO.Get(option);
case option is
when 1 =>
Ada.Text_IO.Put_Line("Shuffle");
when 2 =>
Ada.Text_IO.Put_Line("Pass");
when 3 =>
Skip_Line; -- needed ????
Ada.Text_IO.Put_Line("Enter word: ");
Ada.Text_IO.Get_Line(GuessWord, Last);
when 4 =>
Ada.Text_IO.Put_Line("See you again soon!");
endGame := true;
when others =>
Ada.Text_IO.Put_Line("Invalid Option");
end case;
exception
when ADA.IO_EXCEPTIONS.Data_Error =>
Ada.Text_IO.Put_Line ("Try a number from 1 to 4, Buddy");
skip_line;
end;
end loop;
end Main;
--
Björn
^ permalink raw reply [relevance 4%]
* Re: Error "exception not permitted here" when putting EXCEPTION in a loop
@ 2015-07-18 14:32 4% ` Trish Cayetano
2015-07-18 14:59 4% ` Björn Lundin
0 siblings, 1 reply; 200+ results
From: Trish Cayetano @ 2015-07-18 14:32 UTC (permalink / raw)
On Saturday, July 18, 2015 at 9:55:12 PM UTC+8, björn lundin wrote:
> On 2015-07-18 14:41, Trish Cayetano wrote:
> > Hello Björn,
> >
> > I don't need the inner loop after all.
> > I removed the inner loop but it still run in infinite loops.
>
> it runs fine as long as you do not enter a non-digit.
> Then it seems like the call to
> Ada.Integer_Text_IO.Get(option);
> does not clear the buffer.
>
> if fed a character, Data_error is raised - which is correct.
> But the next time the code enters the loop, it seems it does
> not wait for input again.
> It raises the data_error again, and the infinite loop is there.
>
> Seems like a compiler bug to me, but the behavior of *text_io.get
> has surprised me before.
>
> --
> Björn
Well which reminds me! I added a SKIP_LINE... The expected output is close... It shows the exception error every other input... it waits for 2 inputs and then 1 input and then 2...
REVISED
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with Ada.Numerics.Discrete_Random;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Ada.Text_IO.Unbounded_IO; use Ada.Text_IO.Unbounded_IO;
with Ada.IO_Exceptions; use Ada.IO_Exceptions;
procedure Main is
GuessWord : String(1..20);
last: Natural;
option : Integer := 0;
endGame: Boolean := False;
begin
while not endGame loop
begin
Ada.Text_IO.Put_Line(" | CHOOSE YOUR OPTION: 1)Shuffle 2)Pass 3)Enter Word 4)Exit ");
Skip_Line;
Ada.Integer_Text_IO.Get(option);
exception
when ADA.IO_EXCEPTIONS.Data_Error =>
Ada.Text_IO.Put_Line ("Try a number from 1 to 4, Buddy");
case option is
when 1 =>
Ada.Text_IO.Put_Line("Shuffle");
when 2 =>
Ada.Text_IO.Put_Line("Pass");
when 3 =>
Skip_Line;
Ada.Text_IO.Put_Line("Enter word: ");
Ada.Text_IO.Get_Line(GuessWord, Last);
when 4 =>
Ada.Text_IO.Put_Line("See you again soon!");
endGame := true;
when others =>
Ada.Text_IO.Put_Line("Invalid Option");
end case;
end;
end loop;
end Main;
=====
OUTPUT
C:\Users\a0284014\Desktop\ada\exception\obj\main
| CHOOSE YOUR OPTION: 1)Shuffle 2)Pass 3)Enter Word 4)Exit
e
1
| CHOOSE YOUR OPTION: 1)Shuffle 2)Pass 3)Enter Word 4)Exit
3
| CHOOSE YOUR OPTION: 1)Shuffle 2)Pass 3)Enter Word 4)Exit
e
Try a number from 1 to 4, Buddy
Enter word:
e
| CHOOSE YOUR OPTION: 1)Shuffle 2)Pass 3)Enter Word 4)Exit
r
t
Try a number from 1 to 4, Buddy
Enter word:
r
| CHOOSE YOUR OPTION: 1)Shuffle 2)Pass 3)Enter Word 4)Exit
r
^ permalink raw reply [relevance 4%]
* Re: Error "exception not permitted here" when putting EXCEPTION in a loop
@ 2015-07-18 12:41 4% ` Trish Cayetano
0 siblings, 1 reply; 200+ results
From: Trish Cayetano @ 2015-07-18 12:41 UTC (permalink / raw)
On Saturday, July 18, 2015 at 6:07:12 PM UTC+8, björn lundin wrote:
> On 2015-07-18 10:14, Trish Cayetano wrote:
>
> e is my own code (i removed the functions and others)... S
>
> orry I am really new to Ada. I actually tried also to put
>
> another loop and added declare, begin and end. It
>
> hang after I ran. And when I terminated the process, it looks like it
> ran infinitely in loops.
> >
>
> when you set endGame to true,
> you are in the *inner* loop.
> but the *outer* loop tests for endGame.
>
> How do you exit the *inner* loop?
>
> what purpose has the *inner* loop?
>
> When you have the answer,
> your program will be easy to fix.
>
> --
> Björn
Hello Björn,
I don't need the inner loop after all.
I removed the inner loop but it still run in infinite loops.
REVISED CODE:
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with Ada.Numerics.Discrete_Random;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Ada.Text_IO.Unbounded_IO; use Ada.Text_IO.Unbounded_IO;
with Ada.IO_Exceptions; use Ada.IO_Exceptions;
procedure Main is
GuessWord : String(1..20);
last: Natural;
option : Integer := 0;
endGame: Boolean := False;
begin
while not endGame loop
begin
Ada.Text_IO.Put_Line(" | CHOOSE YOUR OPTION: 1)Shuffle 2)Pass 3)Enter Word 4)Exit ");
Ada.Integer_Text_IO.Get(option);
case option is
when 1 =>
Ada.Text_IO.Put_Line("Shuffle");
when 2 =>
Ada.Text_IO.Put_Line("Pass");
when 3 =>
Skip_Line;
Ada.Text_IO.Put_Line("Enter word: ");
Ada.Text_IO.Get_Line(GuessWord, Last);
when 4 =>
Ada.Text_IO.Put_Line("See you again soon!");
endGame := true;
when others =>
Ada.Text_IO.Put_Line("Invalid Option");
end case;
Skip_Line;
exception
when ADA.IO_EXCEPTIONS.Data_Error =>
Ada.Text_IO.Put_Line ("Try a number from 1 to 4, Buddy");
end;
end loop;
end Main;
RESULT:
C:\Users\a0284014\Desktop\ada\exception\obj\main
| CHOOSE YOUR OPTION: 1)Shuffle 2)Pass 3)Enter Word 4)Exit
f
Try a number from 1 to 4, Buddy
| CHOOSE YOUR OPTION: 1)Shuffle 2)Pass 3)Enter Word 4)Exit
Try a number from 1 to 4, Buddy
| CHOOSE YOUR OPTION: 1)Shuffle 2)Pass 3)Enter Word 4)Exit
Try a number from 1 to 4, Buddy
| CHOOSE YOUR OPTION: 1)Shuffle 2)Pass 3)Enter Word 4)Exit
Try a number from 1 to 4, Buddy
| CHOOSE YOUR OPTION: 1)Shuffle 2)Pass 3)Enter Word 4)Exit
Try a number from 1 to 4, Buddy
[2015-07-18 20:39:33] process exited with status 1, elapsed time: 10.81s
^ permalink raw reply [relevance 4%]
* Re: Error "exception not permitted here" when putting EXCEPTION in a loop
@ 2015-07-18 8:14 3% ` Trish Cayetano
0 siblings, 1 reply; 200+ results
From: Trish Cayetano @ 2015-07-18 8:14 UTC (permalink / raw)
On Friday, July 17, 2015 at 11:58:18 PM UTC+8, G.B. wrote:
> On 17.07.15 17:47, Trish Cayetano wrote:
> > Hi,
> >
> > I am getting error "exception not permitted here" when running below in a loop.
> > Well it runs if I put it outside the loop but I need it inside the loop...
> >
> > exception
> > when ADA.IO_EXCEPTIONS.DATA_ERROR =>
> > Ada.Text_IO.Put_Line ("Try a number from 1 to 4, Buddy");
> >
> > Thanks in advance for your help...
> >
>
> does it look like
>
> loop
> ...
> exception ...
> ...
> end loop
>
> If so, then note that "exception" must be in a block,
> such as a procedure body, or a block statement (LRM 5.6):
>
>
> loop
> begin
> ... -- handled sequence of statements
> exception ...
> ...
> end;
> end loop
>
> More complete examples would help reducing guess work.
Thanks, David and GB.
It still does not work...
Here is my own code (i removed the functions and others)... Sorry I am really new to Ada. I actually tried also to put another loop and added declare, begin and end. It hang after I ran. And when I terminated the process, it looks like it ran infinitely in loops.
=====
--start of code
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with Ada.Numerics.Discrete_Random;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Ada.Text_IO.Unbounded_IO; use Ada.Text_IO.Unbounded_IO;
with Ada.IO_Exceptions; use Ada.IO_Exceptions;
procedure Main is
GuessWord : String(1..20);
last: Natural;
option : Integer := 0;
endGame: Boolean := False;
begin
while not endGame loop
loop
begin
Ada.Text_IO.Put_Line(" | CHOOSE YOUR OPTION: 1)Shuffle 2)Pass 3)Enter Word 4)Exit ");
Ada.Integer_Text_IO.Get(option);
case option is
when 1 =>
Ada.Text_IO.Put_Line("Shuffle");
when 2 =>
Ada.Text_IO.Put_Line("Pass");
when 3 =>
Skip_Line;
Ada.Text_IO.Put_Line("Enter word: ");
Ada.Text_IO.Get_Line(GuessWord, Last);
when 4 =>
Ada.Text_IO.Put_Line("See you again soon!");
endGame := true;
when others =>
Ada.Text_IO.Put_Line("Invalid Option");
end case;
exception
when ADA.IO_EXCEPTIONS.Data_Error =>
Ada.Text_IO.Put_Line ("Try a number from 1 to 4, Buddy");
end;
end loop;
end loop;
end Main;
--end of code
==============
RESULT:
C:\Users\a0284014\Desktop\ada\exception\obj\main
| CHOOSE YOUR OPTION: 1)Shuffle 2)Pass 3)Enter Word 4)Exit
1
Shuffle
| CHOOSE YOUR OPTION: 1)Shuffle 2)Pass 3)Enter Word 4)Exit
e
Try a number from 1 to 4, Buddy
| CHOOSE YOUR OPTION: 1)Shuffle 2)Pass 3)Enter Word 4)Exit
Try a number from 1 to 4, Buddy
| CHOOSE YOUR OPTION: 1)Shuffle 2)Pass 3)Enter Word 4)Exit
Try a number from 1 to 4, Buddy
| CHOOSE YOUR OPTION: 1)Shuffle 2)Pass 3)Enter Word 4)Exit
Try a number from 1 to 4, Buddy
| CHOOSE YOUR OPTION: 1)Shuffle 2)Pass 3)Enter Word 4)Exit
--retracted repeats
[2015-07-18 16:11:13] process exited with status 1, elapsed time: 19.58s
^ permalink raw reply [relevance 3%]
* Re: How to shuffle/jumble letters of a given word?
2015-06-28 21:07 4% ` Simon Wright
@ 2015-06-29 21:45 6% ` MM
1 sibling, 0 replies; 200+ results
From: MM @ 2015-06-29 21:45 UTC (permalink / raw)
On Sunday, 28 June 2015 15:06:29 UTC+1, Trish Cayetano wrote:
> I am creating a "text twist game" where you guess the words in a jumbled manner. How do I set the code to shuffle the letters?
>
> Example: word to be guessed is HELLO
>
> What should be displayed is: LOLEH or LELHO
>
> Thanks in advance!
Here is a rough-and-ready Fisher-Yates shuffle demonstration. This one shuffles whatever line it receives on STDIN (only one line).
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Numerics.Discrete_Random;
procedure Shuffle_String is
function ShuffleRand (N: in Positive) return Integer is
subtype Random_Range is Integer range 1 .. N;
package Random_Shuffle_Integer is new Ada.Numerics.Discrete_Random(Random_Range);
use Random_Shuffle_Integer;
Generator : Random_Shuffle_Integer.Generator;
Retval: Random_Range;
begin
Reset(Generator);
Retval := Random(Generator);
return Retval;
end;
function Shuffle (Item : String) return String is
Result : String (Item'Range);
Temp : Character;
J : Integer;
begin
Result := Item;
for I in reverse Result'first + 1 .. Result'last loop
J := ShuffleRand (I);
Temp := Result (I);
Result (I) := Result (J);
Result (J) := Temp;
end loop;
return Result;
end Shuffle;
begin
Put_Line (Shuffle (Get_Line));
end Shuffle_String;
^ permalink raw reply [relevance 6%]
* Re: How to shuffle/jumble letters of a given word?
2015-06-29 8:05 5% ` Simon Wright
@ 2015-06-29 8:13 0% ` Dmitry A. Kazakov
0 siblings, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2015-06-29 8:13 UTC (permalink / raw)
On Mon, 29 Jun 2015 09:05:50 +0100, Simon Wright wrote:
> "Jeffrey R. Carter" <spam.jrcarter.not@spam.not.acm.org> writes:
>
>> On 06/28/2015 02:07 PM, Simon Wright wrote:
>>>
>>> Then, given a String, create an Elements array with each Key a new
>>> random number and each Ch the corresponding character in the String;
>>> sort it (which, since the Keys were random, is effectively a shuffle);
>>> and return a String formed of the Chs in their new order.
>>
>> You could also just sort the String.
>
> I don't see how this would work?
>
> Though I see I made myself less than clear. At the risk of solving even
> more of the OP's problem for her than I already have,
>
> Keyed : Elements (Str'Range);
> begin
> for J in Str'Range loop
> Keyed (J) := (Ada.Numerics.Float_Random.Random (Gen), Str (J));
It should be non-repeating random numbers in this case, provided
"shuffling" meant permutation.
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
^ permalink raw reply [relevance 0%]
* Re: How to shuffle/jumble letters of a given word?
@ 2015-06-29 8:05 5% ` Simon Wright
2015-06-29 8:13 0% ` Dmitry A. Kazakov
0 siblings, 1 reply; 200+ results
From: Simon Wright @ 2015-06-29 8:05 UTC (permalink / raw)
"Jeffrey R. Carter" <spam.jrcarter.not@spam.not.acm.org> writes:
> On 06/28/2015 02:07 PM, Simon Wright wrote:
>>
>> Then, given a String, create an Elements array with each Key a new
>> random number and each Ch the corresponding character in the String;
>> sort it (which, since the Keys were random, is effectively a shuffle);
>> and return a String formed of the Chs in their new order.
>
> You could also just sort the String.
I don't see how this would work?
Though I see I made myself less than clear. At the risk of solving even
more of the OP's problem for her than I already have,
Keyed : Elements (Str'Range);
begin
for J in Str'Range loop
Keyed (J) := (Ada.Numerics.Float_Random.Random (Gen), Str (J));
end loop;
Sort (Keyed);
^ permalink raw reply [relevance 5%]
* Re: How to shuffle/jumble letters of a given word?
@ 2015-06-28 21:07 4% ` Simon Wright
2015-06-29 21:45 6% ` MM
1 sibling, 1 reply; 200+ results
From: Simon Wright @ 2015-06-28 21:07 UTC (permalink / raw)
Trish Cayetano <trishacayetano@gmail.com> writes:
> I am creating a "text twist game" where you guess the words in a
> jumbled manner. How do I set the code to shuffle the letters?
>
> Example: word to be guessed is HELLO
>
> What should be displayed is: LOLEH or LELHO
You want to take the letters in a random order, so you'll find
Ada.Numerics.Float_Random[1] useful.
You can't just take the random'th character of the original string,
because you mustn't take the same character twice.
One (possibly heavyweight) approach would be to create a new type
containing a float and a character,
type Item is record
Key : Float;
Ch : Character;
end record;
and a type for an array of Items, rather like the String you want to
jumble,
type Elements is array (Positive range <>) of Item;
and then instantiate Ada.Containers.Generic_Array_Sort[2] for Elements.
You'll need a function "<" to compare two Items on the basis of their
Keys, e.g.
function "<" (L, R : Item) return Boolean is (L.Key < R.Key);
Then, given a String, create an Elements array with each Key a new
random number and each Ch the corresponding character in the String;
sort it (which, since the Keys were random, is effectively a shuffle);
and return a String formed of the Chs in their new order.
[1] http://www.ada-auth.org/standards/12rm/html/RM-A-5-2.html
[2] http://www.ada-auth.org/standards/12rm/html/RM-A-18-26.html#p2
^ permalink raw reply [relevance 4%]
* Re: {Pre,Post}conditions and side effects
2015-04-24 8:59 4% ` Jacob Sparre Andersen
2015-04-24 22:26 0% ` Peter Chapin
@ 2015-04-25 0:31 0% ` Bob Duff
1 sibling, 0 replies; 200+ results
From: Bob Duff @ 2015-04-25 0:31 UTC (permalink / raw)
Jacob Sparre Andersen <jacob@jacob-sparre.dk> writes:
> Robert A Duff <bobduff@shell01.TheWorld.com> writes:
>> Peter Chapin <PChapin@vtc.vsc.edu> writes:
>
>>> ... Thus putting anything resembling essential program logic in an
>>> assertion is, of course, just wrong.
>>
>> Yes.
>
> But when are you putting "essential program logic" in an assertion?
I think what Peter meant by "essential program logic" is code that,
if deleted from the program, would cause the program to malfunction.
> 1) subtype Non_Negative_Matrix is Ada.Numerics.Real_Arrays.Real_Matrix
> with Dynamic_Predicate
> => (Non_Negative_Matrix'First (1) = 1) and
> (Non_Negative_Matrix'First (2) = 1) and
> (for all E of Non_Negative_Matrix => E >= 0.0);
>
> 2) procedure New_Line (File : in File_Type)
> with Pre => Is_Open (File) and then
> Mode (File) in (Out_File | Append_File);
The assertions in (1) and (2) are not "essential program logic"; if you
delete them, the program will still work properly. That's fine -- you
should write assertions so that deleting them from a correct program
will have no effect.
> 3) function Binary_Search (Source : in List;
> Key : in Keys) return Values
> with Pre => Sort (Source); -- Sorts Source if it isn't already sorted.
That's illegal. (I assume Sort is a procedure with an 'in out'
parameter that sorts in place. Passing Source (an 'in') parameter is
illegal.) I suppose you could make Source 'in out', but as you say
below that's a very bad idea.
> I consider examples (1) and (2) fine, but example (3) a very bad idea.
Agreed. (3) is trying to put "essential program logic" in an assertion,
which is a bad idea.
> At the same time, I know that my application may fail silently if the
> assertion in example (1) isn't true.
>
> When it comes to example (2), I expect that the operating system (if
> nothing else) will make sure that my application doesn't fail silently
> if the assertion isn't true.
>
> But I dislike banning "essential program logic" in assertions, as any
> assertion is program logic. And if it isn't essential, why should it be
> there?
Same reason we put comments in the code. Comments are not "essential
program logic" in the sense defined above -- if you delete all the
comments, the program will still work. But we still want comments.
Likewise, one should normally write assertions (like Pre and Predicate)
so the program still works if they are deleted.
Assertions are like comments, except we have a higher confidence
that they are actually true.
> One problem I have with assertion aspects is that I get the same
> exception no matter which mistake I have made. If I put the check
> inside a subprogram instead of in its profile, I can get more clear
> information about which kinds of mistakes I make.
You can say:
Pre => X = Y or else raise X_Not_Equal_To_Y;
- Bob
^ permalink raw reply [relevance 0%]
* Re: {Pre,Post}conditions and side effects
2015-04-24 22:26 0% ` Peter Chapin
@ 2015-04-25 0:13 0% ` Randy Brukardt
0 siblings, 0 replies; 200+ results
From: Randy Brukardt @ 2015-04-25 0:13 UTC (permalink / raw)
"Peter Chapin" <PChapin@vtc.vsc.edu> wrote in message
news:alpine.CYG.2.11.1504241811360.5268@WIL414CHAPIN.vtc.vsc.edu...
...
> In a correct program all assertions should always be true.
Sure, but that applies to lots of other things, too. For instance, in a
correct program, Constraint_Error or Program_Error should not be raised. But
it still happens.
>> 1) subtype Non_Negative_Matrix is Ada.Numerics.Real_Arrays.Real_Matrix
>> with Dynamic_Predicate
>> => (Non_Negative_Matrix'First (1) = 1) and
>> (Non_Negative_Matrix'First (2) = 1) and
>> (for all E of Non_Negative_Matrix => E >= 0.0);
>
> Although the Dynamic_Predicate asserts that the matrix elements are all
> non-negative, this does not remove the program's obligation to include
> checks that no negative elements are added to the matrix. The assertion
> only exists to catch mistakes in those checks. It does not exist to
> actually *be* those checks. In that respect the assertion is not
> "essential program logic."
I disagree with this (see below).
>> 2) procedure New_Line (File : in File_Type)
>> with Pre => Is_Open (File) and then
>> Mode (File) in (Out_File | Append_File);
>
> Similarly here the program is still obligated to only pass File objects to
> New_Line that represent open files. If the program accidentally passes an
> unopened file to New_Line the assertion will catch the logical error.
> However, the assertion should not take the place of earlier checks. Again
> the assertion is not essential program logic.
I definitely disagree here. This example is essentially similar to the one
given in the upcoming Corrigendum (3.2.4(41-51/4). In a case like this, the
precondition (or predicates as in the example) *replace* the checks required
by English text in the RM. There would no internal checks of correctness.
You are of course correct that no caller should call New_Line with a closed
file, but that's irrelevant because it can happen anyway (there is no static
way to prevent it). There has to be code somewhere to handle it. So, in such
a case, a precondition serves two purposes: (1) to signal to the client what
conditions are expected, and (2) to determine what happens if those
conditions aren't met. (2) certainly is "essential program logic", at so far
as one cannot meet the published specification of New_Line without it.
Ada prior to Ada 2012 has a problem in that the reasons an exception can be
raised conflate the programmer mistakes with conditions that are impossible
for the programmer to know (consider the difference between whether a file
object is open vs. whether a file exists on the disk). Preconditions and
predicates provide a way to separately specify the first kind of situation
vs. the second kind. (Ultimately, one hopes, compilers will be able to
eliminate much of the runtime checking associated with preconditions and
predicates, which is not possible in the pre-Ada 2012 world.)
Randy.
^ permalink raw reply [relevance 0%]
* Re: {Pre,Post}conditions and side effects
2015-04-24 8:59 4% ` Jacob Sparre Andersen
@ 2015-04-24 22:26 0% ` Peter Chapin
2015-04-25 0:13 0% ` Randy Brukardt
2015-04-25 0:31 0% ` Bob Duff
1 sibling, 1 reply; 200+ results
From: Peter Chapin @ 2015-04-24 22:26 UTC (permalink / raw)
On Fri, 24 Apr 2015, Jacob Sparre Andersen wrote:
> But when are you putting "essential program logic" in an assertion?
I think a servicable rule is this: If the program works as required, with
all necessary checks still present, with all assertions removed, then we
can say the assertions contain no essential program logic.
In a correct program all assertions should always be true.
> 1) subtype Non_Negative_Matrix is Ada.Numerics.Real_Arrays.Real_Matrix
> with Dynamic_Predicate
> => (Non_Negative_Matrix'First (1) = 1) and
> (Non_Negative_Matrix'First (2) = 1) and
> (for all E of Non_Negative_Matrix => E >= 0.0);
Although the Dynamic_Predicate asserts that the matrix elements are all
non-negative, this does not remove the program's obligation to include
checks that no negative elements are added to the matrix. The assertion
only exists to catch mistakes in those checks. It does not exist to
actually *be* those checks. In that respect the assertion is not
"essential program logic."
> 2) procedure New_Line (File : in File_Type)
> with Pre => Is_Open (File) and then
> Mode (File) in (Out_File | Append_File);
Similarly here the program is still obligated to only pass File objects to
New_Line that represent open files. If the program accidentally passes an
unopened file to New_Line the assertion will catch the logical error.
However, the assertion should not take the place of earlier checks. Again
the assertion is not essential program logic.
> 3) function Binary_Search (Source : in List;
> Key : in Keys) return Values
> with Pre => Sort (Source); -- Sorts Source if it isn't already sorted.
Yes, definitely wrong. On the other hand using something like
with Pre => Is_Sorted(Source);
could be reasonable.
> I consider examples (1) and (2) fine, but example (3) a very bad idea.
I agree that (1) and (2) are fine, but that doesn't mean the program
should rely on the assertions for its proper functioning. The assertions
check correctness; they don't implement it. Even if the assertions are
removed, the program should still execute properly.
> But I dislike banning "essential program logic" in assertions, as any
> assertion is program logic. And if it isn't essential, why should it be
> there?
Because we often make mistakes and it's nice to have our thinking double
checked. Also, of course, the assertions make our intentions known to
tools, such as SPARK, that can automatically verify our code implements
the conditions we are asserting.
> One problem I have with assertion aspects is that I get the same
> exception no matter which mistake I have made. If I put the check
> inside a subprogram instead of in its profile, I can get more clear
> information about which kinds of mistakes I make.
Putting the check inside the subprogram is quite a different thing. That
is part of your implementation of correctness. Since assertions should
never fail, using the same exception for all of them isn't terrible. That
said, the upcoming feature that allows different exceptions to be used
when an assertion fails is nice too.
Peter
^ permalink raw reply [relevance 0%]
* Re: {Pre,Post}conditions and side effects
@ 2015-04-24 8:59 4% ` Jacob Sparre Andersen
2015-04-24 22:26 0% ` Peter Chapin
2015-04-25 0:31 0% ` Bob Duff
0 siblings, 2 replies; 200+ results
From: Jacob Sparre Andersen @ 2015-04-24 8:59 UTC (permalink / raw)
Robert A Duff <bobduff@shell01.TheWorld.com> writes:
> Peter Chapin <PChapin@vtc.vsc.edu> writes:
>> ... Thus putting anything resembling essential program logic in an
>> assertion is, of course, just wrong.
>
> Yes.
But when are you putting "essential program logic" in an assertion?
1) subtype Non_Negative_Matrix is Ada.Numerics.Real_Arrays.Real_Matrix
with Dynamic_Predicate
=> (Non_Negative_Matrix'First (1) = 1) and
(Non_Negative_Matrix'First (2) = 1) and
(for all E of Non_Negative_Matrix => E >= 0.0);
2) procedure New_Line (File : in File_Type)
with Pre => Is_Open (File) and then
Mode (File) in (Out_File | Append_File);
3) function Binary_Search (Source : in List;
Key : in Keys) return Values
with Pre => Sort (Source); -- Sorts Source if it isn't already sorted.
I consider examples (1) and (2) fine, but example (3) a very bad idea.
At the same time, I know that my application may fail silently if the
assertion in example (1) isn't true.
When it comes to example (2), I expect that the operating system (if
nothing else) will make sure that my application doesn't fail silently
if the assertion isn't true.
But I dislike banning "essential program logic" in assertions, as any
assertion is program logic. And if it isn't essential, why should it be
there?
One problem I have with assertion aspects is that I get the same
exception no matter which mistake I have made. If I put the check
inside a subprogram instead of in its profile, I can get more clear
information about which kinds of mistakes I make.
Greetings,
Jacob
--
"Any politician with a live opposition does not understand
how to make proper use of the true instruments of politics."
^ permalink raw reply [relevance 4%]
* Re: How to get nice with GNAT?
@ 2014-11-24 3:05 4% ` brbarkstrom
0 siblings, 0 replies; 200+ results
From: brbarkstrom @ 2014-11-24 3:05 UTC (permalink / raw)
On Sunday, November 23, 2014 3:49:38 PM UTC-5, Jeffrey Carter wrote:
> On 11/23/2014 10:41 AM, brbarkstrom wrote:
> >
> > I'm working in GNAT GPL, so my suggestion may not work with every
> > compiler.
> >
> > On the other hand, in my code, the if following the exception in the
> > procedure is picked up and executed properly. The code doesn't act
> > like the program has to fail if any exception is raised.
>
> I don't think you're talking about exceptions. I took this program:
>
> with Ada.Text_IO;
> procedure Boolean_Exception is
> procedure Test (OK : out Boolean) is
> -- empty declarative part
> begin -- Test
> OK := False;
>
> raise Constraint_Error;
> end Test;
>
> OK : Boolean := True;
> begin -- Boolean_Exception
> Test (OK => OK);
> Ada.Text_IO.Put_Line (Item => "No exception");
> exception -- Boolean_Exception
> when others =>
> Ada.Text_IO.Put_Line (Item => Boolean'Image (OK) );
> end Boolean_Exception;
>
> compiled with GNAT 4.6 on Linux, and got:
>
> $ gnatmake -gnatwa -gnatano -O2 -fstack-check boolean_exception.adb
> gcc-4.6 -c -gnatwa -gnatano -O2 -fstack-check boolean_exception.adb
> boolean_exception.adb:6:10: warning: assignment to pass-by-copy formal may have
> no effect
> boolean_exception.adb:6:10: warning: "raise" statement may result in abnormal
> return (RM 6.4.1(17))
> gnatbind -x boolean_exception.ali
> gnatlink boolean_exception.ali -O2 -fstack-check
> $ ./boolean_exception
> TRUE
>
> What you're talking about doesn't work with GNAT.
>
> --
> Jeff Carter
> "This school was here before you came,
> and it'll be here before you go."
> Horse Feathers
> 48
Here's a rather long response to your post:
I don't think you'll get a sensible response when you try to set
Test(OK => True); or Test(OK => False) when the specification of
the procedure Test has OK as an "out" variable. It doesn't make
sense try to set this value as input to a variable that emerges from the procedure (Test).
Here's a slight rewriting of the code you provided:
with Ada.Text_IO;
procedure exception_handling_0 is
procedure test (OK : out Boolean) is
-- empty declarative part
begin -- test
OK := False;
raise Constraint_Error;
end test;
OK : Boolean := True;
begin -- exception_handling_0
test (OK => OK);
Ada.Text_IO.Put_Line (Item => "No exception");
exception
when others =>
Ada.Text_IO.Put_Line (Item => Boolean'Image (OK) );
end exception_handling_0;
The GNAT GPL GPS tool on my Ubuntu 14.04 LTS system returns the
two warnings:
7.10 warning: assignment to pass-by-copy formal may have no effect
7.10 warning: "raise" statement may result in abnormal return
(RM 6.4.1(17))
In other words, a programmer shouldn't expect a variable input to
an "out" variable in the interface specification to have any relation
to whatever is generated in the procedure that is called. Secondly,
an exception raised in the procedure test may result in an abnormal
return. This is hardly a clean piece of code.
When I run it, the output from the code does something that seems
to me to be an abnormal return. It returns the output "TRUE".
The output claims that "the process terminated successfully, ...".
It certainly isn't the expected behavior in a reasonable reading of the
procedure text. Rather it suggests that the compiler completely ignored
whatever went on in the procedure.
Putting the same code into a Windows XP installation of GNAT GPL 2014 with GPS
produces exactly the same warnings, compilation, and output.
In the original source code I provided, I used the following specification
file (called Common_Defs.ads):
with Ada.Characters.Latin_1;
with Ada.Strings;
with Ada.Strings.Bounded;
with Ada.Numerics;
with Ada.Numerics.generic_elementary_functions;
package Common_Defs is
------------------------------------------------------------------------------
-- Generic Packages
------------------------------------------------------------------------------
subtype real is long_float;
package Usr_Math is new
Ada.Numerics.generic_elementary_functions(real);
Std_Vstring_Length : constant := 256;
package VString is new
Ada.Strings.Bounded.Generic_Bounded_Length(Std_Vstring_Length);
Long_Vstring_Lngth : constant := 5000;
package Long_Vstring is new
Ada.Strings.Bounded.Generic_Bounded_Length(Long_Vstring_Lngth);
------------------------------------------------------------------------------
-- Constant
------------------------------------------------------------------------------
TAB : constant Character := Ada.Characters.Latin_1.HT;
end Common_Defs;
Then, I created the source code
with Ada.Text_IO;
with Common_Defs; use Common_Defs;
procedure Test_Exception is
-- Local Procedure Specification
procedure Test (I : in Natural;
OK : out Boolean;
Err_Msg : out Vstring.Bounded_String);
-- Variables
I : Natural := 20;
Test_OK : Boolean;
Err_Msg : Vstring.Bounded_String;
-- Local Procedure Body
procedure Test (I : in Natural;
OK : out Boolean;
Err_Msg : out Vstring.Bounded_String) is
Max_I : Natural := 10;
I_Out_Of_Range : exception;
begin -- Test
OK := False;
Err_Msg := Vstring.To_Bounded_String("procedure Test was not initialized when this message was created.");
if I <= Max_I then
OK := True;
Err_Msg := Vstring.To_Bounded_String("In procedure Test, I as input : ");
Err_Msg := Vstring.Append(Err_Msg, Natural'image(I));
Err_Msg := Vstring.Append(Err_Msg, " was less than or equal to ");
Err_Msg := Vstring.Append(Err_Msg, Natural'image(Max_I));
else
raise I_Out_Of_Range;
end if;
exception
when I_Out_Of_Range =>
Err_Msg := Vstring.To_Bounded_String("In procedure Test, I as input : ");
Err_Msg := Vstring.Append(Err_Msg, Natural'image(I));
Err_Msg := Vstring.Append(Err_Msg, " was greater than ");
Err_Msg := Vstring.Append(Err_Msg, Natural'image(Max_I));
Err_Msg := Vstring.Append(Err_Msg, " which raises the constraint 'I_Out_Of_Range'.");
when others =>
Err_Msg := Vstring.To_Bounded_String("In procedure Test, something unexpected happened.");
end Test;
begin -- Test_Exception
Test (I => 25,
OK => Test_OK,
Err_Msg => Err_Msg);
if Test_OK then
Ada.Text_IO.Put_Line(Vstring.To_String(Err_Msg));
else
Ada.Text_IO.Put_Line(Vstring.To_String(Err_Msg));
end if;
end Test_Exception;
On Windows, this compiles without warnings. After compilation, binding, and linking, it
runs and outputs the message
"In procedure Test, I as input : 25 was greater than 10 which raises the constraint 'I_Out_Of_Range'." It is clear that the initial setting of
OK and Err_Msg in the procedure have been changed as a result of the
operations during execution.
The behavior on the Ubuntu Linux 64-bit installation of GNAT GPL is identical.
My conclusions:
1. One should not call a procedure to input an "out" variable as declared in the spec and
expect it to return values from the interior of the procedure. In this code, the exception is not one of the system exceptions.
Rather, it is one declared normally in accord with the RM (11.1). An exception handler follows the
specification in RM (11.2), where the Examples at the end of this definition show an approach
that the code I've provided follows.
2. The handled sequence of statements allow variables set as "out" in the procedure specification
to appear as legitimate values (even using the "pass-by-copy" rule). Thus, these "out" variables
can guide procedure actions for the calling procedure even when the called
procedure throws an exception.
Bruce B.
^ permalink raw reply [relevance 4%]
* Re: how to analyze clock drift
@ 2014-11-24 1:15 3% ` Dennis Lee Bieber
0 siblings, 0 replies; 200+ results
From: Dennis Lee Bieber @ 2014-11-24 1:15 UTC (permalink / raw)
On Sun, 23 Nov 2014 21:15:05 +0100, Emanuel Berg <embe8573@student.uu.se>
declaimed the following:
>I can explain that, and then add like, "If you were to
>employ this system in a critical setting, it would be
>necessary to have a much more reliable clock to
>trigger the interrupts. Although you can have widely
>diverging results due to many factors, to illustrate
>the lack of periodicity, and to some degree how that
>behaves and fluctuates [I'm referring to the stats
>here], run the program with `-l' and study the
>outputs..." (I'm not going to put it exactly like that,
>but you get the idea.) Is that better?
Well -- but you haven't /tested/ the reliability of the clock itself;
only of the latency in responding to it...
And just to put this back into an Ada context, I did spend some time
hacking (and I confess to the folks for just how badly hacked this is...
I've not used the packages before, and taking stuff from one package
internal form to something I can manipulate for stats took some klutzing
around) my attempt at collecting some data.
-=-=-=-=-=-
-- Simple experiment of Timer/Clock operation
with Text_IO; use Text_IO;
with Ada.Real_Time;
with Ada.Numerics.Generic_Elementary_Functions;
procedure Timer is
package Rt renames Ada.Real_Time;
type Statistic is digits 15;
package M is new Ada.Numerics.Generic_Elementary_Functions (Statistic);
procedure Runner (Ivl : Rt.Time_Span) is
Num_Samples : constant Integer := 500;
Samples : array (1 .. Num_Samples) of Statistic;
-- statistics stuff
Sum : Statistic := 0.0;
Sum_Var : Statistic := 0.0;
Mean : Statistic;
Min : Statistic;
Max : Statistic;
Variance : Statistic;
Start : Rt.Time;
Stop : Rt.Time;
Log_File : File_Type;
use type Rt.Time_Span;
begin
Put_Line ("Generating data for Time span: "
& Duration'Image (Rt.To_Duration (Ivl)));
Create (File => Log_File,
Mode => Out_File,
Name => "T"
& Duration'Image (Rt.To_Duration (Ivl))
& ".log");
New_Line (Log_File);
Put_Line (Log_File, "Data for Rt.Time span: "
& Duration'Image (Rt.To_Duration (Ivl)));
New_Line (Log_File);
-- Just a bit of Rt.Time waster before starting actual loop
-- probably not needed as I'm capturing the Rt.Clock before
-- and after the delay statement
delay until Rt.Clock + Ivl + Ivl;
for I in 1 .. Num_Samples loop
-- capture the Rt.Clock at the start of the Rt.Time delay
Start := Rt.Clock;
-- delay until the captured Rt.Clock plus one Rt.Time-span interval
delay until Start + Ivl;
-- capture the Rt.Clock after the delay expired
Stop := Rt.Clock;
-- record the difference between stop and start Rt.Clock values
-- less the expected interval;
Put_Line (Log_File, Duration'Image (
Rt.To_Duration (Stop - Start - Ivl)));
Samples (I) := Statistic (Rt.To_Duration (Stop - Start - Ivl));
end loop;
-- compute statistics
Min := Samples (1);
Max := Samples (1);
for I in 1 .. Num_Samples loop
Sum := Sum + Samples (I);
if Samples (I) > Max then
Max := Samples (I);
end if;
if Samples (I) < Min then
Min := Samples (I);
end if;
end loop;
Mean := Sum / Statistic (Num_Samples);
for I in 1 .. Num_Samples loop
Sum_Var := Sum_Var + (Samples (I) - Mean) * (Samples (I) - Mean);
end loop;
Variance := Sum_Var / Statistic (Num_Samples - 1);
Put_Line ("Statistics");
New_Line;
Put_Line ("Max: " & Statistic'Image (Max));
Put_Line ("Min: " & Statistic'Image (Min));
Put_Line ("Mean: " & Statistic'Image (Mean));
-- Put_Line ("Variance: " & Statistic'Image (Variance));
Put_Line ("Std. Dev.: " & Statistic'Image (M.Sqrt (Variance)));
New_Line(5);
end Runner;
begin
Put_Line ("Time Span Unit is " &
Duration'Image (Rt.To_Duration (Rt.Time_Span_Unit)));
New_Line;
Runner (Rt.Nanoseconds (1));
Runner (Rt.Nanoseconds (10));
Runner (Rt.Nanoseconds (100));
Runner (Rt.Microseconds (1));
Runner (Rt.Microseconds (10));
Runner (Rt.Microseconds (100));
Runner (Rt.Milliseconds (1));
Runner (Rt.Milliseconds (10));
Runner (Rt.Milliseconds (100));
end Timer;
-=-=-=-=-
Time Span Unit is 0.000000001
Generating data for Time span: 0.000000001
Statistics
Max: 8.45100000000000E-06
Min: 3.00000000000000E-07
Mean: 8.97321999999994E-07
Std. Dev.: 4.72299434498552E-07
Generating data for Time span: 0.000000010
Statistics
Max: 1.80100000000000E-06
Min: 2.91000000000000E-07
Mean: 8.82286000000004E-07
Std. Dev.: 1.24592289815071E-07
Generating data for Time span: 0.000000100
Statistics
Max: 1.40900000000000E-06
Min: 2.01000000000000E-07
Mean: 7.67528000000000E-07
Std. Dev.: 1.59364913224758E-07
Generating data for Time span: 0.000001000
Statistics
Max: 8.12000000000000E-07
Min: 5.09000000000000E-07
Mean: 7.43505999999995E-07
Std. Dev.: 1.25971025885818E-07
Generating data for Time span: 0.000010000
Statistics
Max: 9.31900000000000E-06
Min: 2.63000000000000E-07
Mean: 6.92286000000001E-07
Std. Dev.: 9.61985163666378E-07
Generating data for Time span: 0.000100000
Statistics
Max: 1.59120000000000E-05
Min: 2.15000000000000E-07
Mean: 7.22622000000002E-07
Std. Dev.: 1.10564358388459E-06
Generating data for Time span: 0.001000000
Statistics
Max: 5.10477000000000E-04
Min: 3.43000000000000E-07
Mean: 2.97962600000000E-06
Std. Dev.: 3.19996443996105E-05
Generating data for Time span: 0.010000000
Statistics
Max: 5.31683000000000E-04
Min: 4.19000000000000E-07
Mean: 5.65434000000001E-06
Std. Dev.: 4.44572946856412E-05
Generating data for Time span: 0.100000000
Statistics
Max: 5.01349000000000E-04
Min: 5.74000000000000E-07
Mean: 3.99113399999998E-06
Std. Dev.: 3.06653091148658E-05
-=-=-=-=-
One thing not seen in the above, is that under Windows, there are
uncontrollable events that will throw a data point out to the extreme...
Look at the millisecond data (0.001). The max latency was 5.1E-4, while the
mean was 2.9E-6. In a run of 500 samples, only 2 or 3 data points jumped to
that high value. That's a sign of the OS doing some house-keeping and
blocking the program from responding. But to see it requires plotting the
data -- once seen, one can attempt to explain that data point. Excluding
those data points will bring the mean down a small amount, but will reduce
the standard deviation significantly.
Also note that for intervals less than 1microsecond, the latency swamps
the delay. Even for 1microsecond, the latency is 0.7microseconds (the
numbers shown above are AFTER the expected delay value has been subtracted
from the stop-start clock times, leaving only the latency from delay
expiration to the read).
--
Wulfraed Dennis Lee Bieber AF6VN
wlfraed@ix.netcom.com HTTP://wlfraed.home.netcom.com/
^ permalink raw reply [relevance 3%]
* Gnat Pro Cross compiling
@ 2014-10-16 12:55 5% Nahro Nadir
0 siblings, 0 replies; 200+ results
From: Nahro Nadir @ 2014-10-16 12:55 UTC (permalink / raw)
I am trying to use gnat pro as a cross compiler which use arm-eabi toolchain, but it cannot recognize any Ada packages!!
Here is compilation result:
5:6 "ada.calendar" is not a predefined library unit
2:6 "ada.direct_io" is not a predefined library unit
8:6 "ada.float_text_io" is not a predefined library unit
7:6 "ada.integer_text_io" is not a predefined library unit
10:6 "ada.numerics" is not a predefined library unit
2:6 "ada.text_io" is not a predefined library unit
2:6 "bmp (spec)" depends on "ada.direct_io (spec)"
2:6 "bmp (spec)" depends on "ada.text_io (spec)"
3:6 "serial_net (spec)" depends on "gnat.sockets (spec)"
2:6 "stream (body)" depends on "bmp (spec)"
3:6 "stream (body)" depends on "serial_net (spec)"
3:6 file "g-socket.ads" not found
^ permalink raw reply [relevance 5%]
* Re: array of string
@ 2014-10-07 16:49 6% ` brbarkstrom
0 siblings, 0 replies; 200+ results
From: brbarkstrom @ 2014-10-07 16:49 UTC (permalink / raw)
On Friday, October 3, 2014 7:29:15 PM UTC-4, Stribor40 wrote:
> is there way to declare array of strings to contain something like this..
>
>
>
> a(1)="london"
>
> a(2)""toronto"
>
>
>
> how would i create this?
Constantly. It's a habit now. One advantage is the Bounded_Strings
library in the ARM. It has functions for appending strings, extracting slices,
obtaining single characters, and so on. I've created a package I call
Common_Defs.ads that lets me have a moderately long string (256 characters)
and a very long one (5000 characters). Note also that the Bounded_String
library throws an exception if you try to stuff too many characters into
the string. That provides a reasonable way to filter out strings that could
cause buffer overflows in Web page text inputs.
Here's the code:
with Ada.Characters.Latin_1;
with Ada.Strings;
with Ada.Strings.Bounded;
with Ada.Numerics;
with Ada.Numerics.generic_elementary_functions;
package Common_Defs is
------------------------------------------------------------------------------
-- Generic Packages
------------------------------------------------------------------------------
subtype real is long_float;
package Usr_Math is new
Ada.Numerics.generic_elementary_functions(real);
Std_Vstring_Length : constant := 256;
package VString is new
Ada.Strings.Bounded.Generic_Bounded_Length(Std_Vstring_Length);
Long_Vstring_Lngth : constant := 5000;
package Long_Vstring is new
Ada.Strings.Bounded.Generic_Bounded_Length(Long_Vstring_Lngth);
------------------------------------------------------------------------------
-- Constant
------------------------------------------------------------------------------
TAB : constant Character := Ada.Characters.Latin_1.HT;
end Common_Defs;
This package spec lets me create long_floats and bring along the appropriate
math functions in one fell swoop. If using the compiler default on long_floats
worries you, you can define the numerical type you want and embed it in this
kind of spec. The reason for having the TAB character is if you want to
create TAB-delimited text files that you can feed into spreadsheets. If you
do the usual
with Common_Defs; use Common_Defs;
then you can just use Put(TAB) (or Put(Output_File, TAB)) in Text_IO
interactions.
Bruce B.
^ permalink raw reply [relevance 6%]
* Re: casting types
@ 2014-10-06 23:36 4% ` brbarkstrom
0 siblings, 0 replies; 200+ results
From: brbarkstrom @ 2014-10-06 23:36 UTC (permalink / raw)
On Friday, October 3, 2014 4:29:34 AM UTC-4, Jacob Sparre Andersen wrote:
> Stribor40 wrote:
>
>
>
> > Now I would like to save this 81.00000 as an integer to some
>
> > variable. Can you please show me how to do this please
>
>
>
> You can't do that without having declared (or chosen) an appropriate
>
> integer type, and declared a variable of that type.
>
>
>
> Once that is done, you write:
>
>
>
> Variable := Type (81.00000);
>
>
>
> Greetings,
>
>
>
> Jacob
>
> --
>
> "constructive ambiguity"
First, to be safe in doing any floating point arithmetic, you should
use the Ada type long_float. You can rename this to double or real
if you want. Create a package that that creates a new Ada.Numerics
(or some such - I need to check the definitions I usually use on my Windows
XP machine that doesn't connect to the Web)
Next, the equivalent to type casting is that you can then create a function
like
With Common_Defs; use Common_Defs;
function Multiply(x : in float;
y : in float) return real;
function Multiply(x : in float;
y : in float) return real
is
Result : real;
begin
Result := real(x*y);
return (Result);
end Multiply;
You will reduce both truncation and round-off errors by doing all
floating point computations with Ada long_float variables and
operations. If you do, just replace the "float" types in the
snippet with "real" and carry on. If you need an introduction,
consult Acton, 1970: "Numerical Methods That Work", Haroer & Row.
It's the only book I know on numerical methods that has a sense of
humor - as well as a whole interlude on "What Not To Compute".
Bruce B.
^ permalink raw reply [relevance 4%]
* Re: Benchmark Ada, please
@ 2014-07-05 12:34 4% ` Guillaume Foliard
0 siblings, 0 replies; 200+ results
From: Guillaume Foliard @ 2014-07-05 12:34 UTC (permalink / raw)
Victor Porton wrote:
> Somebody, write an Ada benchmark for this comparison of programming
> languages:
>
> https://github.com/jesusfv/Comparison-Programming-Languages-Economics
Here is it:
---------------------------------------------------------------------
with Ada.Execution_Time;
with Ada.Numerics.Long_Elementary_Functions;
with Ada.Real_Time;
with Ada.Text_IO;
use Ada.Numerics.Long_Elementary_Functions;
use type Ada.Execution_Time.CPU_Time;
procedure Rbc_Ada
is
Grid_Capital_Length : constant := 17820;
Grid_Productivity_Length : constant := 5;
type Grid_Capital_Index is
new Integer range 0 .. Grid_Capital_Length - 1;
type Grid_Productivity_Index is
new Integer range 0 .. Grid_Productivity_Length - 1;
type Grid_Array_Type is
array (Grid_Capital_Index, Grid_Productivity_Index)
of Long_Float;
Null_Grid : constant Grid_Array_Type := (others => (others => 0.0));
-- 1. Calibration
-- Elasticity of output w.r.t. capital
Alpha : constant Long_Float := 0.33333333333;
-- Discount factor
Beta : constant Long_Float := 0.95;
-- Productivity values
Productivities : constant
array (Grid_Productivity_Index)
of Long_Float :=
(0.9792, 0.9896, 1.0000, 1.0106, 1.0212);
-- Transition matrix
Transition : constant
array (Grid_Productivity_Index, Grid_Productivity_Index)
of Long_Float :=
((0.9727, 0.0273, 0.0000, 0.0000, 0.0000),
(0.0041, 0.9806, 0.0153, 0.0000, 0.0000),
(0.0000, 0.0082, 0.9837, 0.0082, 0.0000),
(0.0000, 0.0000, 0.0153, 0.9806, 0.0041),
(0.0000, 0.0000, 0.0000, 0.0273, 0.9727));
-- 2. Steady State
Capital_Steady_State : constant Long_Float :=
(Alpha * Beta) ** (1.0 / (1.0 - Alpha));
Output_Steady_State : constant Long_Float :=
Capital_Steady_State ** Alpha;
Consumption_Steady_State : constant Long_Float :=
Output_Steady_State - Capital_Steady_State;
Grid_Capital_Next_Index : Grid_Capital_Index;
Grid_Capital : array (Grid_Capital_Index) of Long_Float :=
(others => 0.0);
Output : Grid_Array_Type := Null_Grid;
Value_Function : Grid_Array_Type := Null_Grid;
Value_Function_New : Grid_Array_Type := Null_Grid;
Policy_Function : Grid_Array_Type := Null_Grid;
Expected_Value_Function : Grid_Array_Type := Null_Grid;
Max_Difference : Long_Float := 10.0;
Diff : Long_Float;
Diff_High_So_Far : Long_Float;
Tolerance : constant := 0.0000001;
Value_High_So_Far : Long_Float;
Value_Provisional : Long_Float;
Consumption : Long_Float;
Capital_Choice : Long_Float;
Iteration : Integer := 0;
Cpu_Time_Start : Ada.Execution_Time.CPU_Time;
Cpu_Time_End : Ada.Execution_Time.CPU_Time;
begin
Cpu_Time_Start := Ada.Execution_Time.Clock;
Ada.Text_IO.Put_Line
("Output =" & Output_Steady_State'Img
& ", Capital =" & Capital_Steady_State'Img
& ", Consumption =" & Consumption_Steady_State'Img);
-- We generate the grid of capital
for Index in Grid_Capital'Range
loop
Grid_Capital (Index) :=
0.5 * Capital_Steady_State + 0.00001 * Long_Float (Index);
end loop;
-- We pre-build output for each point in the grid
for Productivity_Index in Grid_Productivity_Index
loop
for Capital_Index in Grid_Capital_Index
loop
Output (Capital_Index, Productivity_Index) :=
Productivities (Productivity_Index)
* Grid_Capital (Capital_Index) ** Alpha;
end loop;
end loop;
-- Main iteration
while Max_Difference > Tolerance
loop
for Productivity_Index in Grid_Productivity_Index
loop
for Capital_Index in Grid_Capital_Index
loop
Expected_Value_Function (Capital_Index, Productivity_Index) :=
0.0;
for Productivity_Next_Index in Grid_Productivity_Index
loop
Expected_Value_Function (Capital_Index, Productivity_Index)
:=
Expected_Value_Function (Capital_Index,
Productivity_Index)
+ Transition (Productivity_Index, Productivity_Next_Index)
* Value_Function (Capital_Index, Productivity_Next_Index);
end loop;
end loop;
end loop;
for Productivity_Index in Grid_Productivity_Index
loop
-- We start from previous choice (monotonicity of policy function)
Grid_Capital_Next_Index := 0;
for Capital_Index in Grid_Capital_Index
loop
Value_High_So_Far := -100000.0;
Capital_Choice := Grid_Capital (0);
for Capital_Next_Index in
Grid_Capital_Next_Index .. Grid_Capital_Index'Last
loop
Consumption :=
Output (Capital_Index, Productivity_Index)
- Grid_Capital (Capital_Next_Index);
Value_Provisional :=
(1.0 - Beta) * Log (Consumption)
+ Beta * Expected_Value_Function (Capital_Next_Index,
Productivity_Index);
if Value_Provisional > Value_High_So_Far
then
Value_High_So_Far := Value_Provisional;
Capital_Choice := Grid_Capital (Capital_Next_Index);
Grid_Capital_Next_Index := Capital_Next_Index;
else
exit;
end if;
Value_Function_New (Capital_Index, Productivity_Index) :=
Value_High_So_Far;
Policy_Function (Capital_Index, Productivity_Index) :=
Capital_Choice;
end loop;
end loop;
end loop;
Diff_High_So_Far := -100000.0;
for Productivity_Index in Grid_Productivity_Index
loop
for Capital_Index in Grid_Capital_Index
loop
Diff :=
abs (Value_Function (Capital_Index, Productivity_Index)
- Value_Function_New (Capital_Index,
Productivity_Index));
if Diff > Diff_High_So_Far
then
Diff_High_So_Far := Diff;
end if;
Value_Function (Capital_Index, Productivity_Index)
:= Value_Function_New (Capital_Index, Productivity_Index);
end loop;
end loop;
Max_Difference := Diff_High_So_Far;
Iteration := Iteration + 1;
if Iteration mod 10 = 0 or Iteration = 1
then
Ada.Text_IO.Put_Line ("Iteration =" & Iteration'Img
& ", Sup Diff =" & Max_Difference'Img);
end if;
end loop;
Ada.Text_IO.Put_Line ("Iteration =" & Iteration'Img
& ", Sup Diff =" & Max_Difference'Img);
Ada.Text_IO.New_Line;
Ada.Text_IO.Put_Line ("My check =" & Policy_Function (999, 2)'Img);
Ada.Text_IO.New_Line;
Cpu_Time_End := Ada.Execution_Time.Clock;
Ada.Text_IO.Put_Line
("Elapsed time is ="
& Ada.Real_Time.To_Duration (Cpu_Time_End - Cpu_Time_Start)'Img);
end Rbc_Ada;
---------------------------------------------------------------------
This is mostly a line to line translation from RBC_CPP.cpp. I have
added a few type declarations though.
> It seems that C++ was the fastest (faster than Fortran), but Ada may be
> even faster.
Here are the numbers with GNAT GPL 2014 on a Core2 Q9650 @ 3.00GHz:
$ gnatmake -O3 rbc_ada.adb
$ time ./rbc_ada
...
Elapsed time is = 1.966112682
As for the C++ version:
$ g++ -o testc -O3 RBC_CPP.cpp
$ time ./testc
...
Elapsed time is = 3.12033
So the Ada version is significantly faster. I suppose it is mainly because
the Ada compiler has vectorized more loops than the C++ compiler (add -
ftree-vectorizer-verbose=2 to the above compilation commands to check by
yourself).
> If we succeed, we would advertise Ada as the fastest(!) programming
> language (after assembler).
Feel free to advertise, using this Ada code as you wish.
--
Guillaume Foliard
^ permalink raw reply [relevance 4%]
* Re: Lotto simulation
2014-06-15 20:43 5% ` Simon Wright
@ 2014-06-16 20:22 0% ` Dirk Heinrichs
0 siblings, 0 replies; 200+ results
From: Dirk Heinrichs @ 2014-06-16 20:22 UTC (permalink / raw)
Simon Wright wrote:
> Why mix it?
Thought that would be more realistic.
>> You'd then create a new array of 48 integers filled with the numbers at 1
>> to picked-1 plus picked+1 to 49 of the former array, mix that array again
>> and pick a random index out of 1 to 48. Again remove the number at that
>> index.
>
> But Ada.Numerics.Discrete_Random picks a random value of the
> Result_Subtype it was instantiated with. So if you want to pick a number
> in 1 .. 48 you have to create a new instantiation. And the RNG is going
> to start off in some state, unrelated to the present state of the RNG
> for 1 .. 49. How are you going to be sure that it's not going to return
> 1 every time?
I was just trying to explain how the drawing works in reality w/o having any
concrete Ada solution in mind. IMHO, once one ball is picked, a new
situation is created, that's why I thought a new array would be a good idea.
OTOH, when the values in the array are mixed, would it matter if the RNG
returned 1? It's just the array index.
Bye...
Dirk
--
Dirk Heinrichs <dirk.heinrichs@altum.de>
Tel: +49 (0)2471 209385 | Mobil: +49 (0)176 34473913
GPG Public Key CB614542 | Jabber: dirk.heinrichs@altum.de
Sichere Internetkommunikation: http://www.retroshare.org
^ permalink raw reply [relevance 0%]
* Re: Lotto simulation 2
2014-06-16 8:03 6% Lotto simulation 2 montgrimpulo
@ 2014-06-16 12:21 5% ` Stefan.Lucks
0 siblings, 0 replies; 200+ results
From: Stefan.Lucks @ 2014-06-16 12:21 UTC (permalink / raw)
[-- Attachment #1: Type: TEXT/PLAIN, Size: 1994 bytes --]
> I want to thank all contributors to my first post on Lotto simulation for their valuable input.
> As a conclusion I decided to use the containers.vectors package. Here is my solution. Please
> feel free to comment on any aspect.
Looks OK, in principle. Some of your identifiers may be too short to
understand what is going on (e.g., tz, iz), and, when communicating Ada
source code, you should lean to capitalize identifiers (Tz or TZ, but not
tz), ect ...
Also, it is a little surprising that you don't output your results.
However, my main criticism would be that your usage of Vectors is overkill
for the problem at hand. Here is a solution using a single array, instead
of two containers.
with Ada.Numerics.Discrete_Random, Ada.Text_IO;
procedure Ziehung2 is
subtype Index is Integer range 1 .. 49;
Ball: array(Index) of Index;
begin
-- intialize Ball
for I in Index loop
Ball(I) := I;
end loop;
-- draw six numbers and print them
for I in 0 .. 5 loop
-- invariant: Ball(1 .. Index'Last-I) hold the balls not yet drawn
-- Ball(Index'Last-I+1 .. Index'Last) hold the balls drawn so far
declare
subtype Z is Index range 1 .. Index'Last-I;
package RND is new Ada.Numerics.Discrete_Random(Z);
Gen: RND.Generator;
Drawn, Tmp: Index;
begin
RND.Reset(Gen);
Drawn := Rnd.Random(Gen); -- Drawn := random index
Ada.Text_IO.Put(Index'Image(Ball(Drawn))); -- print Ball(Drawn)
-- move Ball(Drawn) to the end of Ball(1 .. Index'Last-I)
-- more precisely, swap Ball(Index'Last-I) and Ball(Drawn)
Tmp := Ball(Index'Last-I);
Ball(Index'Last-I) := Ball(Drawn);
Ball(Drawn) := Tmp;
end;
end loop;
end Ziehung2
------ I love the taste of Cryptanalysis in the morning! ------
<http://www.uni-weimar.de/cms/medien/mediensicherheit/home.html>
--Stefan.Lucks (at) uni-weimar.de, Bauhaus-Universität Weimar, Germany--
^ permalink raw reply [relevance 5%]
* Re: Lotto simulation
@ 2014-06-16 11:15 5% ` Stefan.Lucks
0 siblings, 0 replies; 200+ results
From: Stefan.Lucks @ 2014-06-16 11:15 UTC (permalink / raw)
[-- Attachment #1: Type: TEXT/PLAIN, Size: 2730 bytes --]
On Mon, 16 Jun 2014, J-P. Rosen wrote:
>> but mathematically, given a uniformly
>> distributed real number F between 0.0 and 1.0, one can get a uniformly
>> distributed discrete D between Low and high: D := Truncate(Low + F *
>> (High-Low + 1)).
> I think it all depends on the definition of "uniformly distributed". If
> it is uniformly distributed among all representable floating point
> numbers (which you get if you take an integer random number and
> unchecked-convert it to Float), you'll get many more values below 0.5
> than above (since the range 0.5..1.0 is represented with only one value
> of the exponent).
Well, do you think the Annotated Reference Manual
<http://www.ada-auth.org/standards/12aarm/html/AA-A-5-2.html> needs a
clarification? It explicitely tells
A sufficiently long sequence of random numbers obtained by successive
calls to Random is approximately uniformly distributed over the range of
the result subtype.
From my point of view, "uniformly distributed over the range of the result
subtype" would seem to imply values > 0.5 to be as often as values < 0.5.
In fact, I would claim that any random generator, choosing floats between
0.0 and 1.0 with a significant bias towards 0.0 or 1.0 would be plain
stupid and worse than useless, and a standard which allows that, would
need urgent repair!
Fortunately, my Ada compiler (gnat) is not such stupid and behaves as I
had expected:
with Ada.Text_IO, Ada.Numerics.Float_Random, Ada.Command_Line;
procedure Test_Rnd is
package ANFR renames Ada.Numerics.Float_Random;
Gen: ANFR.Generator;
High: Natural := 0;
Sample_Size: constant Natural := Natural'Value(Ada.Command_Line.Argument(1));
begin
ANFR.Reset(Gen);
for I in 1 .. Sample_Size loop
if ANFR.Random(Gen) > 0.5 then
High := High + 1;
end if;
end loop;
Ada.Text_IO.Put_Line(Integer'Image(High) &" /"& Integer'Image(Sample_Size));
end Test_Rnd;
Compiling and running the above program indicates an even distribution of
values > 0.5 and <= 0.5 (i.e., there is no statistically significant
bias):
$ ./test_rnd 100000000
49999482 / 100000000
$ ./test_rnd 1000000000
499991845 / 1000000000
Note that the results are biased towards 0.0, but the bias is
statistically insignificant. (It would be statistically strange, indeed,
if *exactly* half of the random values would be below 0.5, and the other
half would be above.)
So long
------ I love the taste of Cryptanalysis in the morning! ------
<http://www.uni-weimar.de/cms/medien/mediensicherheit/home.html>
--Stefan.Lucks (at) uni-weimar.de, Bauhaus-Universität Weimar, Germany--
^ permalink raw reply [relevance 5%]
* Lotto simulation 2
@ 2014-06-16 8:03 6% montgrimpulo
2014-06-16 12:21 5% ` Stefan.Lucks
0 siblings, 1 reply; 200+ results
From: montgrimpulo @ 2014-06-16 8:03 UTC (permalink / raw)
Hi,
I want to thank all contributors to my first post on Lotto simulation for their valuable input.
As a conclusion I decided to use the containers.vectors package. Here is my solution. Please
feel free to comment on any aspect.
with Ada.Numerics.Discrete_Random, Ada.Text_IO, Ada.Containers.Vectors;
use Ada.Containers;
procedure Ziehung is
package IO renames Ada.Text_IO;
package ball_container is new Vectors (Positive, Positive);
balls, iball : ball_container.Vector;
tz, iz : Integer;
begin
balls.Set_Length (Length => 49);
iball.Set_Length (Length => 6);
for i in 1 .. 49 loop
balls.Replace_Element (Index => i, New_Item => i);
end loop;
tz := 49;
for i in 1 .. 6 loop
lottoblock : declare
subtype z is Positive range 1 .. tz;
package lb is new Ada.Numerics.Discrete_Random (z);
glb : lb.Generator;
begin
lb.Reset (glb);
iz := lb.Random (glb);
end lottoblock;
iball.Replace_Element
(Index => i, New_Item => balls.Element (Index => iz));
balls.Delete (Index => iz, Count => 1);
tz := tz - 1;
end loop;
IO.Put_Line ("Length_b:" & balls.Length'Img);
IO.Put_Line ("Length_ib:" & iball.Length'Img);
end Ziehung;
Length_b: 43
Length_ib: 6
[2014-06-16] process terminated successfully, elapsed time: 00.21s
^ permalink raw reply [relevance 6%]
* Re: Lotto simulation
@ 2014-06-15 20:43 5% ` Simon Wright
2014-06-16 20:22 0% ` Dirk Heinrichs
0 siblings, 1 reply; 200+ results
From: Simon Wright @ 2014-06-15 20:43 UTC (permalink / raw)
Dirk Heinrichs <dirk.heinrichs@altum.de> writes:
> montgrimpulo wrote:
>
>> this is a placeholder of the task which I am trying to solve in Ada.
>> As you may know in German Lotto there are 49 numbers 1..49
>> from which you have to select 6 numbers to place a bet.
>>
>> Second Round:
>> Here does my problem start. Now I have a set of numbers where
>> one number - which was randomly selected in the first round -
>> is missing. How do I use the random function to select another
>> random number out of the rest ?
>>
>> Any ideas to answer that question ?
>
> Let's look at how it works in reality: A random ball is selected out of a
> set of 49 balls, mixed randomly before the pick, resulting in a new set of
> 48 balls, etc.
>
> So you'd need to start with a sorted array of integers 1 to 49, mix it
> randomly and then pick a random index out of 1 to 49. The number at that
> index is then removed from the array.
Why mix it?
> You'd then create a new array of 48 integers filled with the numbers at 1 to
> picked-1 plus picked+1 to 49 of the former array, mix that array again and
> pick a random index out of 1 to 48. Again remove the number at that index.
But Ada.Numerics.Discrete_Random picks a random value of the
Result_Subtype it was instantiated with. So if you want to pick a number
in 1 .. 48 you have to create a new instantiation. And the RNG is going
to start off in some state, unrelated to the present state of the RNG
for 1 .. 49. How are you going to be sure that it's not going to return
1 every time?
^ permalink raw reply [relevance 5%]
* Re: Lotto simulation
@ 2014-06-15 18:54 4% ` Stefan.Lucks
1 sibling, 1 reply; 200+ results
From: Stefan.Lucks @ 2014-06-15 18:54 UTC (permalink / raw)
[-- Attachment #1: Type: TEXT/PLAIN, Size: 2306 bytes --]
On Sun, 15 Jun 2014, montgrimpulo wrote:
> this is a placeholder of the task which I am trying to solve in Ada.
> As you may know in German Lotto there are 49 numbers 1..49
> from which you have to select 6 numbers to place a bet.
>
> First Round:
> By defining a subtype valid for positive numbers from 1 .. 49,
> the use of Ada.Discrete_Random, and the definition of an appropriate Generator
> you may get a random number in the range of 1 .. 49.
Call that number R_1.
> Second Round:
> Here does my problem start. Now I have a set of numbers where
> one number - which was randomly selected in the first round -
> is missing. How do I use the random function to select another
> random number out of the rest ?
There are a couple of different solutions.
First Solution (in pseudo-code, not in Ada):
repeat choose a random R_2 between 1 and 49
until R_2 /= R_1.
Third round: Choose a random R_3 between 1 and 49
until R_3 /= R_1 and R_3 /= R_2.
ect.
Second Solution:
choose a random R_2 between 1 and 48
If R_2=R_1 then R_1 := 49
choose a random R_3 between 1 and 47
If R_3=R_1 then R_3 := 48
elsif R_3=R_2 then R_3 := 49
ect.
Now, for the second solution, you need random numbers from different
intervals. In principle, you can (2a) instantiate a new generator from
Ada.Numerics.Discrete_Random for each of the R_i. The alternative is to
(2n) instantiate a single random generator (I've forgotten the package
name, but it is not A.N.Discrete_Random), which just generates a Float
F_Rand between 0 and 1. Then set R_I := Truncate(1 + F_Rand * (50-I)).
> A workaround would be
> to test in each round, if that number has already been selected.
> However, the probability would not be the same as with a reduced
> set as the selection would be always from the full set.
That sounds like my first solution. If you repeat the random choice until
you R_i is different from all the R_(i-1), ..., R_1, the probability is
exactly the probability you expect. (Well, assuming the random generator
is good.)
------ I love the taste of Cryptanalysis in the morning! ------
<http://www.uni-weimar.de/cms/medien/mediensicherheit/home.html>
--Stefan.Lucks (at) uni-weimar.de, Bauhaus-Universität Weimar, Germany--
^ permalink raw reply [relevance 4%]
* Re: OT: A bit of Sudoku
@ 2014-06-06 14:13 2% ` Brad Moore
0 siblings, 0 replies; 200+ results
From: Brad Moore @ 2014-06-06 14:13 UTC (permalink / raw)
On 14-06-05 05:39 PM, Adam Beneschan wrote:
> On Thursday, June 5, 2014 4:12:55 PM UTC-7, Robert A Duff wrote:
>
>> In any case, if you need to jump out of many layers of (recursive?)
>> calls, an exception might well be the best way. Checking error
>> codes at each level might be verbose and error prone.
>
> I don't like it. But if you do something like this, I'd suggest that this use be limited to an exception that you declare inside a subprogram, so that you raise and handle it only inside that subprogram or nested subprograms. Otherwise, someone could look at a subprogram that is called in between, and never guess that the subprogram might not complete normally (A calls B, B calls C, C raises an exception that gets passed over B's head back to A; a programmer trying to read B might not suspect that B may not complete in a non-error situation.) In other words, keep such usages as localized as possible.
>
> Another thing to keep in mind is that exceptions cause overhead. I've seen implementations that have to do some stuff any time a subprogram or a block with an exception handler is entered. I've seen other implementations that, in order to eliminate this overhead in "normal" (non-exception) cases, perform table lookups on each address in the stack until it finds a handler; this is a relatively expensive operation that those implementations have decided is justified because exceptions aren't supposed to happen in "normal" cases. Whether this overhead is less than the expense of going through a number of returns, I don't know--I'm sure it depends on various factors. But efficiency should not be a reason to use exceptions instead of straight returns, because it may well make things slower.
>
Another point to keep in mind is that although the exception mechanism
may or may not be technically faster than the normal recursion exit,
depending on implementation, it may not be noticeably faster. A
guideline I try to follow generally is to write the code naturally and
simply, and let the compiler worry about performance, and then only look
at using different constructs if there is still a performance problem
that needs to be addressed.
I have actually written a sudoku solver, that executes in Parallel.
My approach was to just let the recursion unwind naturally.
In my parallelism framework, workers tasks catch and handle exceptions,
where if exceptions are raised in multiple worker threads, only one of
those exceptions is saved, and gets reraised in the calling thread
before returning from the parallel call.
Here exceptions are generally used to report failures, but could
probably be used to report a solution in this case. However if a
different exception occurs in a worker thread (such as a constraint
error), that may or may not be the exception that ends up getting reported.
I suspect that trying to use exceptions to report solutions for Sudoku,
would not noticeably improve performance, as most of the time is spent
trying to find a solution, not report it.
My Sudoku solver uses a brute force approach. (I was mostly interested
in trying out the parallelism). I believe the performance could be
improved significantly by updating local cells to maintain a list of
possible values, thus ruling out trial values much more sooner.
I would think such an approach would improve performance far more than
using exceptions to exit recursion, so that would be where I would
suggest programming effort be spent.
I have several versions of the solver.
(A sequential version,
A load balancing version,
A load balanciong version that adds some stack safety (prevents stack
overflow)
Here is my sequential version. I'd be happy to share the other versions
also....
Brad
generic
N : Positive := 3;
package Sequential_Sudoku is
Max_Range : constant Positive := N**2;
subtype Sudoku_Value is
Natural range 0 .. Max_Range;
Null_Value : constant Sudoku_Value := 0;
subtype Sudoku_Solution_Value is Sudoku_Value range 1 .. Max_Range;
subtype Sudoku_Index is Sudoku_Solution_Value;
type Sudoku_Board is private;
procedure Initialize (Board : in out Sudoku_Board);
function Get
(Board : Sudoku_Board;
Row, Column : Sudoku_Index) return Sudoku_Value;
procedure Set
(Board : in out Sudoku_Board;
Row, Column : Sudoku_Index;
Value : Sudoku_Solution_Value)
with Pre => Is_Valid (Board, Row, Column, Value),
Post => Get (Board, Row, Column) = Value;
function Is_Valid (Board : Sudoku_Board;
Row, Column : Sudoku_Index;
Value : Sudoku_Solution_Value) return Boolean;
procedure Generate (Board : out Sudoku_Board);
procedure Solve (Board : in out Sudoku_Board);
private
type Sudoku_Value_Array is
array (Sudoku_Index, Sudoku_Index) of Sudoku_Value;
type Sudoku_Board is
record
Initialized : Boolean := False;
Values : Sudoku_Value_Array;
end record;
function Get (Board : Sudoku_Board;
Row, Column : Sudoku_Index) return Sudoku_Value is
(Board.Values (Row, Column));
function Value_In_Row
(Board : Sudoku_Board;
Row : Sudoku_Index;
Value : Sudoku_Solution_Value) return Boolean is
(for some I in Board.Values'Range (2) => Board.Values (Row, I) =
Value);
function Value_In_Column
(Board : Sudoku_Board;
Col : Sudoku_Index;
Value : Sudoku_Solution_Value) return Boolean is
(for some I in Board.Values'Range (1) => Board.Values (I, Col) =
Value);
function On_Diagonal
(Board : Sudoku_Board;
Row, Col : Sudoku_Index) return Boolean is
(Row = Col or else Row + Col = Max_Range + 1);
function Value_In_Diagonal
(Board : Sudoku_Board;
Row, Col : Sudoku_Index;
Value : Sudoku_Solution_Value) return Boolean;
-- function Value_In_Diagonal
-- (Board : Sudoku_Board;
-- Row, Col : Sudoku_Index;
-- Value : Sudoku_Solution_Value) return Boolean is
-- (if Row = Col then
-- (for some I in Board.Values'Range (1) =>
-- Board.Values (I, I) = Value)
-- or else
-- (for some I in Board.Values'Range (1) =>
-- Board.Values (Max_Range + 1 - I, I) = Value));
function Value_In_Sector
(Board : Sudoku_Board;
Row, Col : Sudoku_Index;
Value : Sudoku_Solution_Value) return Boolean;
function Is_Valid (Board : Sudoku_Board;
Row, Column : Sudoku_Index;
Value : Sudoku_Solution_Value) return Boolean is
(Board.Initialized and then
not Value_In_Row (Board, Row, Value) and then
not Value_In_Column (Board, Column, Value) and then
not Value_In_Sector (Board, Row, Column, Value)
-- and then
-- (not On_Diagonal (Board, Row, Column) or else not
-- Value_In_Diagonal (Board, Row, Column, Value))
);
end Sequential_Sudoku;
with Ada.Numerics.Discrete_Random;
package body Sequential_Sudoku is
package Random_Index is new Ada.Numerics.Discrete_Random
(Result_Subtype => Sudoku_Index);
procedure Random_Solution
(Board : out Sudoku_Board);
function Multiple_Solutions_Exist
(Board : Sudoku_Board) return Boolean;
Generator : Random_Index.Generator;
procedure Generate (Board : out Sudoku_Board)
is
Scratch_Board : Sudoku_Board;
begin
Random_Solution (Board);
Filter_Loop : loop
declare
Delete_Row : constant Sudoku_Index :=
Random_Index.Random (Generator);
Delete_Column : constant Sudoku_Index :=
Random_Index.Random (Generator);
Delete_Value : constant Sudoku_Value :=
Board.Values (Delete_Row, Delete_Column);
begin
if Delete_Value /= 0 then
Board.Values (Delete_Row, Delete_Column) := 0;
Scratch_Board := Board;
if Multiple_Solutions_Exist (Board => Scratch_Board) then
Board.Values (Delete_Row, Delete_Column) :=
Delete_Value;
exit Filter_Loop;
end if;
end if;
end;
end loop Filter_Loop;
end Generate;
----------------
-- Initialize --
----------------
procedure Initialize (Board : in out Sudoku_Board) is
begin
for I in Board.Values'Range (1) loop
for J in Board.Values'Range (2) loop
Board.Values (I, J) := Null_Value;
end loop;
end loop;
Board.Initialized := True;
end Initialize;
function Multiple_Solutions_Exist
(Board : Sudoku_Board) return Boolean is
-- Note: We do not need to worry about deallocating scratch boards
-- that were allocated from the heap, since they will all get
-- automatically deallocated when this access type goes out of
scope,
-- i.e. before returning from Solve
type Board_Access is access all Sudoku_Board;
type Sudoku_Work is
record
Row, Column : Sudoku_Index'Base;
Scratch_Board : Board_Access;
end record;
Multiple_Solutions : Boolean := False;
protected Solution_Checker is
procedure Note_Solution;
private
Solved : Boolean := False;
end Solution_Checker;
protected body Solution_Checker is
procedure Note_Solution is
begin
if Solved then
Multiple_Solutions := True;
else
Solved := True;
end if;
end Note_Solution;
end Solution_Checker;
function Next_Work (Row : Sudoku_Index'Base := 0;
Column : Sudoku_Index'Base := 1;
Board : Board_Access) return Sudoku_Work
is
Next_Row : Sudoku_Index'Base := Row;
Next_Column : Sudoku_Index'Base := Column;
begin
Search_Loop : loop
Next_Row := Next_Row + 1;
if Next_Row > Max_Range then
Next_Row := 1;
Next_Column := Next_Column + 1;
if Next_Column > Max_Range then
Solution_Checker.Note_Solution;
return (Row => Sudoku_Index'Last,
Column => Sudoku_Index'Last,
Scratch_Board => null);
end if;
end if;
exit Search_Loop when Get (Board.all,
Next_Row,
Next_Column) = 0;
end loop Search_Loop;
return (Row => Next_Row,
Column => Next_Column,
Scratch_Board => Board);
end Next_Work;
procedure Solution_Check_Sequential (Work : Sudoku_Work) is
begin
if Multiple_Solutions or else Work.Scratch_Board = null then
-- No need to worry about deleting any outstanding boards,
-- Once we return from Solve, all boards get deleted,
since the
-- access type gets finalized
return;
end if;
-- Try all values
for I in Sudoku_Index'Range loop
if Is_Valid (Board => Work.Scratch_Board.all,
Row => Work.Row,
Column => Work.Column,
Value => I) then
-- Same worker proceeds to continue work on same board
-- Try another solution
Work.Scratch_Board.all.Values
(Work.Row, Work.Column) := I;
Solution_Check_Sequential
(Next_Work (Row => Work.Row,
Column => Work.Column,
Board => Work.Scratch_Board));
-- Solution didn't work, undo
Work.Scratch_Board.all.Values
(Work.Row, Work.Column) := 0;
end if;
end loop;
end Solution_Check_Sequential;
Scratch_Board : aliased Sudoku_Board := Board;
begin
Solution_Check_Sequential
(Work => Next_Work (Board => Scratch_Board'Access));
return Multiple_Solutions;
end Multiple_Solutions_Exist;
---------------------------------------------------------------
procedure Random_Solution (Board : out Sudoku_Board) is
-- Note: We do not need to worry about deallocating scratch boards
-- that were allocated from the heap, since they will all get
-- automatically deallocated when this access type goes out of
scope,
-- i.e. before returning from Solve
type Board_Access is access all Sudoku_Board;
type Sudoku_Work is
record
Row, Column : Sudoku_Index'Base;
Scratch_Board : Board_Access;
end record;
Done : Boolean := False;
protected Store_Result is
procedure Store (Result : Sudoku_Board);
end Store_Result;
protected body Store_Result is
procedure Store (Result : Sudoku_Board) is
begin
Board := Result;
Done := True;
end Store;
end Store_Result;
function Next_Work (Row : Sudoku_Index'Base := 0;
Column : Sudoku_Index'Base := 1;
Board : Board_Access) return Sudoku_Work;
procedure Generate_Random_Solution (Work : Sudoku_Work)
is
Start_Value : constant Sudoku_Solution_Value :=
Random_Index.Random (Generator);
begin
if Done then
-- No need to worry about deleting any outstanding boards,
-- Once we return from Solve, all boards get deleted,
since the
-- access type gets finalized
return;
end if;
-- Try all values
for I in Sudoku_Index'Range loop
declare
Value : constant Sudoku_Solution_Value :=
(if I + Start_Value - 1 > Max_Range then
I + Start_Value - 1 - Max_Range else I + Start_Value
- 1);
begin
if Is_Valid (Board => Work.Scratch_Board.all,
Row => Work.Row,
Column => Work.Column,
Value => Value) then
-- Same worker proceeds to continue work on same board
-- Try another solution
Work.Scratch_Board.all.Values
(Work.Row, Work.Column) := Value;
Generate_Random_Solution
(Next_Work (Row => Work.Row,
Column => Work.Column,
Board => Work.Scratch_Board));
-- Solution didn't work, undo
Work.Scratch_Board.all.Values
(Work.Row, Work.Column) := 0;
end if;
end;
end loop;
end Generate_Random_Solution;
function Next_Work (Row : Sudoku_Index'Base := 0;
Column : Sudoku_Index'Base := 1;
Board : Board_Access) return Sudoku_Work
is
Next_Row : Sudoku_Index'Base := Row;
Next_Column : Sudoku_Index'Base := Column;
begin
Search_Loop : loop
Next_Row := Next_Row + 1;
if Next_Row > Max_Range then
Next_Row := 1;
Next_Column := Next_Column + 1;
if Next_Column > Max_Range then
Store_Result.Store (Board.all);
return (Row => Sudoku_Index'Last,
Column => Sudoku_Index'Last,
Scratch_Board => null);
end if;
end if;
exit Search_Loop when Get (Board.all,
Next_Row,
Next_Column) = 0;
end loop Search_Loop;
return (Row => Next_Row,
Column => Next_Column,
Scratch_Board => Board);
end Next_Work;
Scratch_Board : aliased Sudoku_Board := Board;
begin
Initialize (Scratch_Board);
Generate_Random_Solution (Next_Work (Board => Scratch_Board'Access));
end Random_Solution;
---------------------------------------------------------------
procedure Set
(Board : in out Sudoku_Board;
Row, Column : Sudoku_Index;
Value : Sudoku_Solution_Value) is
begin
Board.Values (Row, Column) := Value;
end Set;
---------------------------------------------------------------
procedure Solve (Board : in out Sudoku_Board) is
-- Note: We do not need to worry about deallocating scratch boards
-- that were allocated from the heap, since they will all get
-- automatically deallocated when this access type goes out of
scope,
-- i.e. before returning from Solve
type Board_Access is access all Sudoku_Board;
type Sudoku_Work is
record
Row, Column : Sudoku_Index'Base;
Scratch_Board : Board_Access;
end record;
Done : Boolean := False;
protected Store_Result is
procedure Store (Result : Sudoku_Board);
private
Solved : Boolean := False;
end Store_Result;
protected body Store_Result is
procedure Store (Result : Sudoku_Board) is
begin
if not Solved then
Board := Result;
Solved := True;
Done := True;
end if;
end Store;
end Store_Result;
function Next_Work (Row : Sudoku_Index'Base := 0;
Column : Sudoku_Index'Base := 1;
Board : Board_Access) return Sudoku_Work
is
Next_Row : Sudoku_Index'Base := Row;
Next_Column : Sudoku_Index'Base := Column;
begin
Search_Loop : loop
Next_Row := Next_Row + 1;
if Next_Row > Max_Range then
Next_Row := 1;
Next_Column := Next_Column + 1;
if Next_Column > Max_Range then
Store_Result.Store (Board.all);
return (Row => Sudoku_Index'Last,
Column => Sudoku_Index'Last,
Scratch_Board => null);
end if;
end if;
exit Search_Loop when Get (Board.all,
Next_Row,
Next_Column) = 0;
end loop Search_Loop;
return (Row => Next_Row,
Column => Next_Column,
Scratch_Board => Board);
end Next_Work;
procedure Solve_Sequential (Work : Sudoku_Work) is
begin
if Done then
-- No need to worry about deleting any outstanding boards,
-- Once we return from Solve, all boards get deleted,
since the
-- access type gets finalized
return;
end if;
-- Try all values
for I in Sudoku_Index'Range loop
if Is_Valid (Board => Work.Scratch_Board.all,
Row => Work.Row,
Column => Work.Column,
Value => I) then
-- Same worker proceeds to continue work on same board
-- Try another solution
Work.Scratch_Board.all.Values
(Work.Row, Work.Column) := I;
Solve_Sequential (Next_Work (Row => Work.Row,
Column => Work.Column,
Board => Work.Scratch_Board));
-- Solution didn't work, undo
Work.Scratch_Board.all.Values
(Work.Row, Work.Column) := 0;
end if;
end loop;
end Solve_Sequential;
Scratch_Board : aliased Sudoku_Board := Board;
begin
Solve_Sequential (Next_Work (Board => Scratch_Board'Access));
end Solve;
---------------------------------------------------------------
function Value_In_Diagonal
(Board : Sudoku_Board;
Row, Col : Sudoku_Index;
Value : Sudoku_Solution_Value) return Boolean is
begin
if Row = Col then
return
(for some I in Board.Values'Range (1) =>
Board.Values (I, I) = Value);
else
return
(for some I in Board.Values'Range (1) =>
Board.Values (Max_Range + 1 - I, I) = Value);
end if;
end Value_In_Diagonal;
---------------------------------------------------------------
function Value_In_Sector
(Board : Sudoku_Board;
Row, Col : Sudoku_Index;
Value : Sudoku_Solution_Value)
return Boolean
is
Start_Row : constant Sudoku_Index :=
1 + ((Sudoku_Index'Base (Row) - 1) / N) * N;
Start_Col : constant Sudoku_Index :=
1 + ((Sudoku_Index'Base (Col) - 1) / N) * N;
begin
for I in Start_Row .. Start_Row + N - 1 loop
for J in Start_Col .. Start_Col + N - 1 loop
if Board.Values (I, J) = Value then
return True;
end if;
end loop;
end loop;
return False;
end Value_In_Sector;
end Sequential_Sudoku;
^ permalink raw reply [relevance 2%]
* Re: Statistics
2014-04-09 6:37 0% ` Statistics Simon Wright
@ 2014-04-09 21:58 0% ` Poul-Erik Andreasen
1 sibling, 0 replies; 200+ results
From: Poul-Erik Andreasen @ 2014-04-09 21:58 UTC (permalink / raw)
On 09/04/14 08:37, Simon Wright wrote:
> Poul-Erik Andreasen <poulerik69@gmail.com> writes:
>
>> most of what
>> i need is in Ada.numerics
>
> If you need asymmetric matrices, you might find Ada 2005 Math Extensions
> useful.
>
> http://sourceforge.net/projects/gnat-math-extn/
>
Thanks
I will take a look at it. The vekctor things may be usefull.
--
Venlig hilsen
Poul-Erik Andreasen
^ permalink raw reply [relevance 0%]
* Re: Statistics
@ 2014-04-09 9:52 5% ` Simon Wright
0 siblings, 0 replies; 200+ results
From: Simon Wright @ 2014-04-09 9:52 UTC (permalink / raw)
"J-P. Rosen" <rosen@adalog.fr> writes:
> Le 09/04/2014 08:37, Simon Wright a écrit :
>> If you need asymmetric matrices, you might find Ada 2005 Math Extensions
>> useful.
>>
>> http://sourceforge.net/projects/gnat-math-extn/
> Out of curiosity: it is presented as Gnat-specific. Why?
It used to use Interfaces.Fortran.BLAS, which was removed in GNAT GPL
2012/GCC 4.7. AdaCore reimplemented Ada.Numerics to improve portability
(to systems that don't have BLAS, LAPACK) at the expense of performance.
The body of Ada_Numerics.Generic_Arrays now says
with Interfaces.Fortran;
with System.Generic_Array_Operations;
and I think the latter is a GNAT unit? (of course, anyone could copy it;
it doesn't look unusual aside from a pragma Inline_Always).
Also, I don't have any other Ada 2005 compiler!
The library needs BLAS and LAPACK, easy enough on Mac OS X and Debian,
apparently a PITA on Windows.
^ permalink raw reply [relevance 5%]
* Re: Statistics
2014-04-09 0:24 5% ` Statistics Poul-Erik Andreasen
@ 2014-04-09 6:37 0% ` Simon Wright
2014-04-09 21:58 0% ` Statistics Poul-Erik Andreasen
0 siblings, 2 replies; 200+ results
From: Simon Wright @ 2014-04-09 6:37 UTC (permalink / raw)
Poul-Erik Andreasen <poulerik69@gmail.com> writes:
> most of what
> i need is in Ada.numerics
If you need asymmetric matrices, you might find Ada 2005 Math Extensions
useful.
http://sourceforge.net/projects/gnat-math-extn/
^ permalink raw reply [relevance 0%]
* Re: Statistics
@ 2014-04-09 0:24 5% ` Poul-Erik Andreasen
2014-04-09 6:37 0% ` Statistics Simon Wright
0 siblings, 1 reply; 200+ results
From: Poul-Erik Andreasen @ 2014-04-09 0:24 UTC (permalink / raw)
On 08/04/14 23:34, gautier_niouzes@hotmail.com wrote:
> Hi,
> You may want to have a look at MathPaqs:
> http://sf.net/projects/mathpaqs/
> there is a "samples" packages in the stats subdirectory.
> No KDE so far, though, just plain histograms.
> There are also some random simuation tools.
> HTH
> _________________________
> Gautier's Ada programming
> http://sf.net/users/gdemont
>
Thanks
That may bee just what i need. I have decide to
make the KDE my self the math is not that awful,
The formulas are at at Wikipedia and most of what
i need is in Ada.numerics. I take look at
Mathpags to see if there some useful stuff for me there.
--
Venlig hilsen
Poul-Erik Andreasen
^ permalink raw reply [relevance 5%]
* Re: Increasing GNAT's heap
@ 2013-11-12 19:30 7% ` Georg Bauhaus
0 siblings, 0 replies; 200+ results
From: Georg Bauhaus @ 2013-11-12 19:30 UTC (permalink / raw)
On 12.11.13 15:00, Dmitry A. Kazakov wrote:
> On Tue, 12 Nov 2013 14:26:42 +0100, Georg Bauhaus wrote:
>
>> On 12.11.13 12:09, Dmitry A. Kazakov wrote:
>>> Does anybody know a way to increase the heap size available for GNAT? It
>>> crashes with famous GNAT BUG DETECTED, Storage_Error heap exhausted.
>>
>> Do ulimit values have any effect?
>
> $ ulimit
> unlimited
FWIW, I am finding it difficult to trigger something beyond
"Storage_Error heap exhausted" (no bug, i.e.); SE seems kind
of expected for some amounts of memory requested. The program below
tries to make the memory manager commit, by forcing random inits
of the memory at random positions. The program runs quite
a while before either me interrupting it at 2**34 storage elements
(Mac OS X 10.7.5), or some Linux VMs duly reporting STORAGE_ERROR
while processing the memory for 2**32.
Both systems are 64 bit, though, so I can't tell what 32 bit gives as
results. I'm curious. Does this trigger a bug box in your system?
(size_t and others are there for hysteric raisins of comparison.)
with System.Storage_Elements; use System.Storage_Elements;
with Ada.Unchecked_Deallocation;
with Ada.Numerics.Discrete_Random, Ada.Numerics.Elementary_Functions;
with Ada.Text_IO;
procedure Alloc_Ada
is
-- powers of 2, for growing allocated sizes:
Small : constant := 16;
Large : constant := 40;
type Void_Ptr is access Storage_Array;
subtype size_t is Storage_Offset;
package Size_T_IO is new Ada.Text_IO.Integer_IO (size_t);
use Size_T_IO, Ada.Text_IO;
procedure Init (Object : Void_Ptr; Acc : out Storage_Element);
-- Initialize some of Object with random data. Place something
-- almost anywhere in the allocated area, assuming that doing so
-- will require commits.
procedure Free is
new Ada.Unchecked_Deallocation (Storage_Array, Void_Ptr);
procedure Init (Object : Void_Ptr; Acc : out Storage_Element) is
subtype Places is Storage_Offset range 0 .. Object'Length - 1;
package Arb is new Ada.Numerics.Discrete_Random (Storage_Element);
package Pos is new Ada.Numerics.Discrete_Random (Places);
package Math renames Ada.Numerics.Elementary_Functions;
G : Arb.Generator;
P : Pos.Generator;
Offset, Previous_Offset : Storage_Offset := 0;
No_Of_Inits : constant Natural :=
2**(Natural (Math.Log (Float (Object'Length), 2.0))
-
(Small - 4));
begin
Arb.Reset (G); Pos.Reset (P);
Acc := 0;
for Run in 1 .. No_Of_Inits loop
Previous_Offset := Offset;
Offset := Pos.Random (P);
Object (Offset) := Arb.Random (G);
Acc := Acc / 2
+ (Object (Previous_Offset) + Object (Offset)) / 4;
end loop;
end Init;
Buffer : Void_Ptr;
Kept : Storage_Element;
begin
for Power in size_t range Small .. Large loop
Put ("At "); Put (Power);
Put (" ("); Put (2**Natural (Power)); Put (")");
Buffer := new Storage_Array (0 .. 2**Natural (Power));
Init (Buffer, Acc => Kept);
Put_Line (Storage_Element'Image (Kept));
Free (Buffer);
end loop;
end Alloc_Ada;
^ permalink raw reply [relevance 7%]
* Re: How to include shared code
2013-09-19 0:17 4% How to include shared code Emanuel Berg
@ 2013-09-19 7:20 0% ` Dmitry A. Kazakov
0 siblings, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2013-09-19 7:20 UTC (permalink / raw)
On Thu, 19 Sep 2013 02:17:52 +0200, Emanuel Berg wrote:
> If I have two files:
>
> protected_buffer.adb
> bounded_buffer.adb
>
> and those compile and run fine.
>
> But, in both those, I have this piece of code:
>
> function Random_Integer return integer is
> type Span is range 1..9;
> package Random_Integer is new Ada.Numerics.Discrete_Random(Span);
> Seed : Random_Integer.Generator;
> begin
> Random_Integer.Reset(seed);
> Outcome := Random_Integer.Random(seed);
You should keep the generator object (and instantiation of its type)
outside the function that calls it. You also would not reset it each time
you call it. You do this just once after the generator object creation and
only if you want the sequence generated to vary with each program start
(see ARM A.5.2(28).
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
^ permalink raw reply [relevance 0%]
* How to include shared code
@ 2013-09-19 0:17 4% Emanuel Berg
2013-09-19 7:20 0% ` Dmitry A. Kazakov
0 siblings, 1 reply; 200+ results
From: Emanuel Berg @ 2013-09-19 0:17 UTC (permalink / raw)
If I have two files:
protected_buffer.adb
bounded_buffer.adb
and those compile and run fine.
But, in both those, I have this piece of code:
function Random_Integer return integer is
type Span is range 1..9;
package Random_Integer is new Ada.Numerics.Discrete_Random(Span);
Seed : Random_Integer.Generator;
Outcome : Span;
begin
Random_Integer.Reset(seed);
Outcome := Random_Integer.Random(seed);
return INTEGER(Outcome);
end Random_Integer;
function Random_Period return Time_Span is
begin
return Milliseconds(Random_Integer*100);
end Random_Period;
Now, how can I extract that piece of code from both files, and put
it into another file, say, random_period.adb, and then "include"
it into each of the above files (that operate in isolation)?
--
Emanuel Berg - programmer (hire me! CV below)
computer projects: http://user.it.uu.se/~embe8573
internet activity: http://home.student.uu.se/embe8573
^ permalink raw reply [relevance 4%]
* Re: ³A Comparison of Four Pseudo Random Number Generators Implemented in Ada²
2013-07-20 0:18 0% ` Jeffrey Carter
@ 2013-07-20 0:41 0% ` Yannick Duchêne (Hibou57)
0 siblings, 0 replies; 200+ results
From: Yannick Duchêne (Hibou57) @ 2013-07-20 0:41 UTC (permalink / raw)
Le Sat, 20 Jul 2013 02:18:38 +0200, Jeffrey Carter
<spam.jrcarter.not@spam.not.acm.org> a écrit:
> On 07/19/2013 03:07 PM, Bill Findlay wrote:
>>
>> Why not use Ada.Numerics.{Discrete,Float}_Random ?
>
> Those are excellent when you don't care what sequence of values you get
> from the generator with different compilers or different platforms, but
> in those cases where you need to portably obtain the same sequence for
> the same seed value(s), you need to use something else.
Also and more basically, it's often suggested to not rely on a single
generator and use at least two ones, different enough, for comparison of
results, as most papers about Monte Carlo methods introduces this. That's
after all just like with hash functions.
You may also favour algorithms (either in mathematical or comprehensible
source form) over libraries when, as you say, you want to be able to
reproduce an exact same sequence without a record of it (may weight too
much, easily some hundreds of MB), or else want the same in different
contexts, say Ada and SML without external binding.
And above all, this paper mentions Ada and put it at the front, so that's
a lot worthy anyway :-D
--
“Syntactic sugar causes cancer of the semi-colons.” [1]
“Structured Programming supports the law of the excluded muddle.” [1]
[1]: Epigrams on Programming — Alan J. — P. Yale University
^ permalink raw reply [relevance 0%]
* Re: ³A Comparison of Four Pseudo Random Number Generators Implemented in Ada²
2013-07-19 22:07 5% ` ³A Comparison of Four Pseudo Random Number Generators Implemented in Ada² Bill Findlay
@ 2013-07-20 0:18 0% ` Jeffrey Carter
2013-07-20 0:41 0% ` Yannick Duchêne (Hibou57)
0 siblings, 1 reply; 200+ results
From: Jeffrey Carter @ 2013-07-20 0:18 UTC (permalink / raw)
On 07/19/2013 03:07 PM, Bill Findlay wrote:
>
> Why not use Ada.Numerics.{Discrete,Float}_Random ?
Those are excellent when you don't care what sequence of values you get from the
generator with different compilers or different platforms, but in those cases
where you need to portably obtain the same sequence for the same seed value(s),
you need to use something else.
--
Jeff Carter
"You a big nose have it."
Never Give a Sucker an Even Break
107
^ permalink raw reply [relevance 0%]
* Re: ³A Comparison of Four Pseudo Random Number Generators Implemented in Ada²
@ 2013-07-19 22:07 5% ` Bill Findlay
2013-07-20 0:18 0% ` Jeffrey Carter
0 siblings, 1 reply; 200+ results
From: Bill Findlay @ 2013-07-19 22:07 UTC (permalink / raw)
On 19/07/2013 20:28, in article op.w0hhpusdule2fv@cardamome, "Yannick
Duchêne (Hibou57)" <yannick_duchene@yahoo.fr> wrote:
> I was searching the web for simple pseudo‑random number generator suitable
> for Monte Carlo simulation, when I found a paper comparing some PRNG
> implemented in Ada. Don't know if it well suited for simulation and
> “calculation” based on random input, but probably always worth to be
> mentioned here :-p
Why not use Ada.Numerics.{Discrete,Float}_Random ?
--
Bill Findlay
with blueyonder.co.uk;
use surname & forename;
^ permalink raw reply [relevance 5%]
* Re: GNAT does not consistently raise an exception to log(0.0)
2013-07-13 7:26 6% ` Dmitry A. Kazakov
@ 2013-07-14 3:51 0% ` Jerry
0 siblings, 0 replies; 200+ results
From: Jerry @ 2013-07-14 3:51 UTC (permalink / raw)
On Saturday, July 13, 2013 12:26:18 AM UTC-7, Dmitry A. Kazakov wrote:
> On Fri, 12 Jul 2013 17:52:08 -0700 (PDT), Jerry wrote:
>
> > When the following program is built with any of theses compilers:
> >
> > GNATMAKE GPL 2013 (20130314) (downloaded from AdaCore)
> > GNATMAKE GPL 2011 (20110419) (downloaded from AdaCore)
> > GNATMAKE 4.8.0 (Simon Wright's build)
> >
> > like this:
> >
> > $ gnatmake -f bomb_log.adb -OX
> >
> > then if X = 0 (zero) the expected exception is raised and reported thusly:
> >
> > raised CONSTRAINT_ERROR : a-ngelfu.adb:744 explicit raise
> >
> > else if X > 0 no exception is raised.
> >
> > with Ada.Numerics.Long_Elementary_Functions;
> > use Ada.Numerics.Long_Elementary_Functions;
> > procedure Bomb_Log is
> > x : Long_Float;
> > begin
> > x := log(0.0);
> > end Bomb_Log;
>
> You should always be careful about bogus IEEE 754 semantics when using
> numeric operations. I presume that your machine has Long_Float implemented
> by machine's IEEE 754. log returns NaN or -Inf.
It's Intel hardware. GNAT does not allow the request for log(0.0) to even get to the hardwdare because it special-cases it in a-ngelfu.adb:744:
elsif X = 0.0 then
raise Constraint_Error;
>When you turn optimization
> -O2 it slips through. I cannot tell how consistent is that with RM, I
> presume it is. Maybe -O0 should not raise Constrant_Error. I am not a
> language lawyer.
>
> Anyway, in order to enforce sane numeric semantics you do:
>
> with Ada.Numerics.Long_Elementary_Functions;
> use Ada.Numerics.Long_Elementary_Functions;
> procedure Bomb_Log is
> subtype Proper_Float is Long_Float range Long_Float'Range;
> x : Proper_Float;
> begin
> x := log(0.0);
> end Bomb_Log;
>
> This should work as expected.
I'll look into this, but it messes up a lot of other stuff like the nice stuff in Annex G.3, I suppose.
Jerry
>
> > However, under the same conditions as above, the following program raises
> > the exception always:
> >
> > with Ada.Numerics.Long_Elementary_Functions;
> > use Ada.Numerics.Long_Elementary_Functions;
> > with Ada.Text_IO;
> > use Ada.Text_IO;
> > procedure Bomb_Log is
> > x : Long_Float;
> > begin
> > x := log(0.0);
> > Put_Line(Long_Float'Image(x));
> > end Bomb_Log;
>
> I suppose that here you get the exception rather from Long_Float'Image,
> when it stumbles on NaN or whatever garbage log returned.
>
> --
> Regards,
> Dmitry A. Kazakov
> http://www.dmitry-kazakov.de
^ permalink raw reply [relevance 0%]
* Re: GNAT does not consistently raise an exception to log(0.0)
2013-07-13 9:37 0% ` AdaMagica
@ 2013-07-14 3:44 0% ` Jerry
0 siblings, 0 replies; 200+ results
From: Jerry @ 2013-07-14 3:44 UTC (permalink / raw)
On Saturday, July 13, 2013 2:37:20 AM UTC-7, AdaMagica wrote:
> On Saturday, July 13, 2013 2:52:08 AM UTC+2, Jerry wrote:
> > with Ada.Numerics.Long_Elementary_Functions;
> > use Ada.Numerics.Long_Elementary_Functions;
> > procedure Bomb_Log is
> > x : Long_Float;
> > begin
> > x := log(0.0);
> > end Bomb_Log;
> >
> > However, under the same conditions as above, the following program raises the exception always:
> >
> > with Ada.Numerics.Long_Elementary_Functions;
> > use Ada.Numerics.Long_Elementary_Functions;
> > with Ada.Text_IO;
> > use Ada.Text_IO;
> > procedure Bomb_Log is
> > x : Long_Float;
> > begin
> > x := log(0.0);
> > Put_Line(Long_Float'Image(x));
> > end Bomb_Log;
>
> That's easy. In the first version, the compiler optimizes X away, since it's not used for any external effects.
Yes, as Simon has also shown with the generated code differences.
>
> In the second version, you output an invalid value.
No--I only attempt to output an invalid value. The Put_Line is never executed because the exception is raised before that, at the log(0.0) level.
> See RM on allowed optimizations.
I suppose that would be 11.6(5):
http://www.adaic.org/resources/add_content/standards/12rm/html/RM-11-6.html
Jerry
^ permalink raw reply [relevance 0%]
* Re: GNAT does not consistently raise an exception to log(0.0)
2013-07-13 7:34 0% ` Simon Wright
@ 2013-07-14 3:42 6% ` Jerry
0 siblings, 0 replies; 200+ results
From: Jerry @ 2013-07-14 3:42 UTC (permalink / raw)
On Saturday, July 13, 2013 12:34:36 AM UTC-7, Simon Wright wrote:
> Jerry writes:
>
> > $ gnatmake -f bomb_log.adb -OX
> >
> > then if X = 0 (zero) the expected exception is raised and reported thusly:
> >
> > raised CONSTRAINT_ERROR : a-ngelfu.adb:744 explicit raise
> >
> > else if X > 0 no exception is raised.
> >
> >
> > with Ada.Numerics.Long_Elementary_Functions;
> > use Ada.Numerics.Long_Elementary_Functions;
> > procedure Bomb_Log is
> > x : Long_Float;
> > begin
> > x := log(0.0);
> > end Bomb_Log;
>
> If you compile with -gnatwa (most warnings), the report is
>
> bomb_log.adb:4:05: warning: variable "x" is assigned but never read
> bomb_log.adb:6:05: warning: useless assignment to "x", value never referenced
>
> and at -O1 or greater the compiler takes the opportunity to eliminate
> the call of log, because of
>
> pragma Pure (Long_Elementary_Functions);
>
> so that the generated code (gnatmake -c -u -f -S bomb_log.adb) is
>
> .text
> .globl __ada_bomb_log
> __ada_bomb_log:
> LFB1:
> ret
Well, that nails it down, doesn't it.
Interestingly, if I change the program to have a second line with a seond variable y:
with Ada.Numerics.Long_Elementary_Functions;
use Ada.Numerics.Long_Elementary_Functions;
procedure Bomb_Log is
x, y : Long_Float;
begin
x := log(0.0);
y := 2.0 * x;
end Bomb_Log;
there is no warning about "x" but the warnings are now about "y" being assigned but not read, and never being referenced. So the optimzizer still sniffs it out. And Constraint_Error is still raised or not raised in excactly the same conditions as in my original post.
>
> If you change the code to
>
> procedure Bomb_Log is
> x : Long_Float with Volatile;
> begin
> x := log(0.0);
> end Bomb_Log;
>
> (that's -gnat12, of course, use pragma Volatile (X); otherwise) then
> things work as you had expected:
>
> .text
> .globl __ada_bomb_log
> __ada_bomb_log:
> LFB1:
> subq $24, %rsp
> LCFI0:
> xorpd %xmm0, %xmm0
> call _ada__numerics__long_elementary_functions__log
> movsd %xmm0, 8(%rsp)
> addq $24, %rsp
> LCFI1:
> ret
I'll look into Volitile.
Jerry
^ permalink raw reply [relevance 6%]
* Re: GNAT does not consistently raise an exception to log(0.0)
2013-07-13 0:52 7% GNAT does not consistently raise an exception to log(0.0) Jerry
2013-07-13 7:26 6% ` Dmitry A. Kazakov
2013-07-13 7:34 0% ` Simon Wright
@ 2013-07-13 9:37 0% ` AdaMagica
2013-07-14 3:44 0% ` Jerry
2 siblings, 1 reply; 200+ results
From: AdaMagica @ 2013-07-13 9:37 UTC (permalink / raw)
On Saturday, July 13, 2013 2:52:08 AM UTC+2, Jerry wrote:
> with Ada.Numerics.Long_Elementary_Functions;
> use Ada.Numerics.Long_Elementary_Functions;
> procedure Bomb_Log is
> x : Long_Float;
> begin
> x := log(0.0);
> end Bomb_Log;
>
> However, under the same conditions as above, the following program raises the exception always:
>
> with Ada.Numerics.Long_Elementary_Functions;
> use Ada.Numerics.Long_Elementary_Functions;
> with Ada.Text_IO;
> use Ada.Text_IO;
> procedure Bomb_Log is
> x : Long_Float;
> begin
> x := log(0.0);
> Put_Line(Long_Float'Image(x));
> end Bomb_Log;
That's easy. In the first version, the compiler optimizes X away, since it's not used for any external effects.
In the second version, you output an invalid value.
See RM on allowed optimizations.
^ permalink raw reply [relevance 0%]
* Re: GNAT does not consistently raise an exception to log(0.0)
2013-07-13 0:52 7% GNAT does not consistently raise an exception to log(0.0) Jerry
2013-07-13 7:26 6% ` Dmitry A. Kazakov
@ 2013-07-13 7:34 0% ` Simon Wright
2013-07-14 3:42 6% ` Jerry
2013-07-13 9:37 0% ` AdaMagica
2 siblings, 1 reply; 200+ results
From: Simon Wright @ 2013-07-13 7:34 UTC (permalink / raw)
Jerry <lanceboyle@qwest.net> writes:
> $ gnatmake -f bomb_log.adb -OX
>
> then if X = 0 (zero) the expected exception is raised and reported thusly:
>
> raised CONSTRAINT_ERROR : a-ngelfu.adb:744 explicit raise
>
> else if X > 0 no exception is raised.
>
>
> with Ada.Numerics.Long_Elementary_Functions;
> use Ada.Numerics.Long_Elementary_Functions;
> procedure Bomb_Log is
> x : Long_Float;
> begin
> x := log(0.0);
> end Bomb_Log;
If you compile with -gnatwa (most warnings), the report is
bomb_log.adb:4:05: warning: variable "x" is assigned but never read
bomb_log.adb:6:05: warning: useless assignment to "x", value never referenced
and at -O1 or greater the compiler takes the opportunity to eliminate
the call of log, because of
pragma Pure (Long_Elementary_Functions);
so that the generated code (gnatmake -c -u -f -S bomb_log.adb) is
.text
.globl __ada_bomb_log
__ada_bomb_log:
LFB1:
ret
If you change the code to
procedure Bomb_Log is
x : Long_Float with Volatile;
begin
x := log(0.0);
end Bomb_Log;
(that's -gnat12, of course, use pragma Volatile (X); otherwise) then
things work as you had expected:
.text
.globl __ada_bomb_log
__ada_bomb_log:
LFB1:
subq $24, %rsp
LCFI0:
xorpd %xmm0, %xmm0
call _ada__numerics__long_elementary_functions__log
movsd %xmm0, 8(%rsp)
addq $24, %rsp
LCFI1:
ret
^ permalink raw reply [relevance 0%]
* Re: GNAT does not consistently raise an exception to log(0.0)
2013-07-13 0:52 7% GNAT does not consistently raise an exception to log(0.0) Jerry
@ 2013-07-13 7:26 6% ` Dmitry A. Kazakov
2013-07-14 3:51 0% ` Jerry
2013-07-13 7:34 0% ` Simon Wright
2013-07-13 9:37 0% ` AdaMagica
2 siblings, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2013-07-13 7:26 UTC (permalink / raw)
On Fri, 12 Jul 2013 17:52:08 -0700 (PDT), Jerry wrote:
> When the following program is built with any of theses compilers:
>
> GNATMAKE GPL 2013 (20130314) (downloaded from AdaCore)
> GNATMAKE GPL 2011 (20110419) (downloaded from AdaCore)
> GNATMAKE 4.8.0 (Simon Wright's build)
>
> like this:
>
> $ gnatmake -f bomb_log.adb -OX
>
> then if X = 0 (zero) the expected exception is raised and reported thusly:
>
> raised CONSTRAINT_ERROR : a-ngelfu.adb:744 explicit raise
>
> else if X > 0 no exception is raised.
>
> with Ada.Numerics.Long_Elementary_Functions;
> use Ada.Numerics.Long_Elementary_Functions;
> procedure Bomb_Log is
> x : Long_Float;
> begin
> x := log(0.0);
> end Bomb_Log;
You should always be careful about bogus IEEE 754 semantics when using
numeric operations. I presume that your machine has Long_Float implemented
by machine's IEEE 754. log returns NaN or -Inf. When you turn optimization
-O2 it slips through. I cannot tell how consistent is that with RM, I
presume it is. Maybe -O0 should not raise Constrant_Error. I am not a
language lawyer.
Anyway, in order to enforce sane numeric semantics you do:
with Ada.Numerics.Long_Elementary_Functions;
use Ada.Numerics.Long_Elementary_Functions;
procedure Bomb_Log is
subtype Proper_Float is Long_Float range Long_Float'Range;
x : Proper_Float;
begin
x := log(0.0);
end Bomb_Log;
This should work as expected.
> However, under the same conditions as above, the following program raises
> the exception always:
>
> with Ada.Numerics.Long_Elementary_Functions;
> use Ada.Numerics.Long_Elementary_Functions;
> with Ada.Text_IO;
> use Ada.Text_IO;
> procedure Bomb_Log is
> x : Long_Float;
> begin
> x := log(0.0);
> Put_Line(Long_Float'Image(x));
> end Bomb_Log;
I suppose that here you get the exception rather from Long_Float'Image,
when it stumbles on NaN or whatever garbage log returned.
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
^ permalink raw reply [relevance 6%]
* GNAT does not consistently raise an exception to log(0.0)
@ 2013-07-13 0:52 7% Jerry
2013-07-13 7:26 6% ` Dmitry A. Kazakov
` (2 more replies)
0 siblings, 3 replies; 200+ results
From: Jerry @ 2013-07-13 0:52 UTC (permalink / raw)
When the following program is built with any of theses compilers:
GNATMAKE GPL 2013 (20130314) (downloaded from AdaCore)
GNATMAKE GPL 2011 (20110419) (downloaded from AdaCore)
GNATMAKE 4.8.0 (Simon Wright's build)
like this:
$ gnatmake -f bomb_log.adb -OX
then if X = 0 (zero) the expected exception is raised and reported thusly:
raised CONSTRAINT_ERROR : a-ngelfu.adb:744 explicit raise
else if X > 0 no exception is raised.
with Ada.Numerics.Long_Elementary_Functions;
use Ada.Numerics.Long_Elementary_Functions;
procedure Bomb_Log is
x : Long_Float;
begin
x := log(0.0);
end Bomb_Log;
However, under the same conditions as above, the following program raises the exception always:
with Ada.Numerics.Long_Elementary_Functions;
use Ada.Numerics.Long_Elementary_Functions;
with Ada.Text_IO;
use Ada.Text_IO;
procedure Bomb_Log is
x : Long_Float;
begin
x := log(0.0);
Put_Line(Long_Float'Image(x));
end Bomb_Log;
Jerry
P.S. What is the meaning of -O99999 as a gnatmake argument?
^ permalink raw reply [relevance 7%]
* Slow? Ada??
@ 2013-07-12 1:01 5% ` Bill Findlay
0 siblings, 0 replies; 200+ results
From: Bill Findlay @ 2013-07-12 1:01 UTC (permalink / raw)
I was amused to read this ...
On 11/07/2013 00:21, in article krkq9u$fo9$1@loke.gir.dk, "Randy Brukardt"
<randy@rrsoftware.com> wrote:
...
> For things like Sine, the best one can do is copy an implementation from a
> cookbook -- it makes no sense to even imagine trying to create a new one.
...for reasons nothing to do with that controversy.
When debugging Whetstone Algol under my KDF9 emulator I looked at the KDF9
assembly code programming of the arctan function and was completely baffled
by it, so I asked my former colleague, Michael Jamieson to investigate.
He successfully reconstructed the mathemetics behind it, which are very
non-obvious (to put it mildly).
A couple of days ago I idly wondered how well this 50 years old algorithm
would compare with modern implementations, so I wrote a test program to race
it against GNAT GPL 2013's arctan. I expected to find that 2013 would spank
1963's botty. To my astonishment, the old algorithm was faster.
Digging down, I found that Ada.Numerics.Long_Elementary_Functions.arctan
does quite a bit of argument range reduction and result error checking, but
finally invokes the "fpatan" opcode of the x86_64 CPU.
The 1963 algorithm, expressed in Ada 2012 but compiled with aggressive
optimization, is only 17% slower than that single CPU opcode!
Note also that, although it was designed for a machine with 48-bit floating
point, it gets the same accuracy as the hardware method on a machine with
64-bit floating point.
Here is the code, with the observed results included as commentary:
with Ada.Numerics.Long_Elementary_Functions;
with Ada.Text_IO;
with CPU_Timing;
with System.Machine_Code;
use Ada.Numerics.Long_Elementary_Functions;
use Ada.Text_IO;
use CPU_Timing;
use System.Machine_Code;
procedure arctan_test64 is
-- typical output:
-- R = 100000000 evaluations
-- checksum = 5.00000005000000E+07, loop time per repetition = 6 ns
-- checksum = 4.38824577044418E+07, P51V15 time per evaluation = 49 ns
-- checksum = 4.38824577044418E+07, arctan time per evaluation = 53 ns
-- checksum = 4.38824577044418E+07, fpatan time per evaluation = 41 ns
-- P51V15 is the KDF9 algorithm used in Whetstone Algol, ca. 1963
-- See http://www.findlayw.plus.com/KDF9/Arctan%20Paper.pdf
type vector is array (0..5) of Long_Float;
V : constant vector := ( 28165298.0 / 1479104550.0,
28165300.0 / 1479104550.0,
56327872.0 / 1479104550.0,
113397760.0 / 1479104550.0,
179306496.0 / 1479104550.0,
1073741824.0 / 1479104550.0);
function P51V15 (x : Long_Float) return Long_Float with Inline;
function P51V15 (x : Long_Float)
return Long_Float is
A : Long_Float := 1.0;
S : Long_Float := V(0);
B : vector;
begin
B(0) := sqrt(x*x + 1.0);
-- 4 AGM (Arithmetic-Geometric Mean) cycles give a set of values ...
for i in 0..3 loop
A := (A+B(i)) * 0.5;
B(i+1) := sqrt(A*B(i));
end loop;
-- ... that is subjected to a convergence acceleration process:
for i in 1..5 loop
S := S + V(i)*B(i-1);
end loop;
return x / S;
end P51V15;
-- this is the hardware arctan function of the x86_64 Core i7 CPU
function fpatan (X : Long_Float) return Long_Float with Inline;
function fpatan (X : Long_Float)
return Long_Float is
Result : Long_Float;
begin
Asm(Template => "fld1"
& Character'Val(10) -- LF
& Character'Val(9) -- HT
& "fpatan",
Outputs => Long_Float'Asm_Output ("=t", Result),
Inputs => Long_Float'Asm_Input ("0", X));
return Result;
end fpatan;
R : constant := 1e8; -- number of loop repetitions
function ns_per_rep (c : CPU_Usage_in_Microseconds)
return Natural is
begin
return Natural(c * 1e3 / R);
end ns_per_rep;
x : Long_Float;
c : CPU_Timer;
l : CPU_Usage_in_Microseconds;
t : CPU_Usage_in_Microseconds;
begin
Put_Line("R =" & Integer'Image(R) & " evaluations");
-- determine the fixed overhead time
x := 0.0;
Reset_Timer(c);
for i in 1..R loop
x := x + Long_Float(i)/Long_Float(R);
end loop;
l := User_CPU_Time_Since(c);
Put_Line("checksum =" & x'Img & ", "
& "loop time per repetition ="
& Natural'Image(ns_per_rep(l)) & " ns");
x := 0.0;
Reset_Timer(c);
for i in 1..R loop
x := x + P51V15(Long_Float(i)/Long_Float(R));
end loop;
t := User_CPU_Time_Since(c) - l;
Put_Line("checksum =" & x'Img & ", "
& "P51V15 time per evaluation ="
& Natural'Image(ns_per_rep(t)) & " ns");
x := 0.0;
Reset_Timer(c);
for i in 1..R loop
x := x + arctan(Long_Float(i)/Long_Float(R));
end loop;
t := User_CPU_Time_Since(c) - l;
Put_Line("checksum =" & x'Img & ", "
& "arctan time per evaluation ="
& Natural'Image(ns_per_rep(t)) & " ns");
x := 0.0;
Reset_Timer(c);
for i in 1..R loop
x := x + fpatan(Long_Float(i)/Long_Float(R));
end loop;
t := User_CPU_Time_Since(c) - l;
Put_Line("checksum =" & x'Img & ", "
& "fpatan time per evaluation ="
& Natural'Image(ns_per_rep(t)) & " ns");
end arctan_test64;
The difference in time between Ada.Numerics.Long_Elementary_Functions.arctan
and the fpatan function above is due to the afore-mentioned range reduction
and checking. The KDF9 programmers in 1963 were less punctillious about
such matters than we rightly expect Ada to be nowadays.
--
Bill Findlay
with blueyonder.co.uk;
use surname & forename;
^ permalink raw reply [relevance 5%]
* Re: Seeking for papers about tagged types vs access to subprograms
2013-05-16 13:10 0% ` Peter C. Chapin
@ 2013-05-16 13:54 4% ` Dmitry A. Kazakov
0 siblings, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2013-05-16 13:54 UTC (permalink / raw)
On Thu, 16 May 2013 09:10:11 -0400, Peter C. Chapin wrote:
> On Thu, 16 May 2013, Dmitry A. Kazakov wrote:
>
>>>> So,
>>>>
>>>> X, Y : Driver;
>>>>
>>>> have same values?
>>>
>>> Yes, I would say so.
>>
>> Really? X is an *equivalent* of Y?
>
> Sure. If it were allowed the expression 'X = Y' should return True.
If X嚙踝蕭Y, you don't need two instances of.
> I realize that equivalence of functions is a difficult concept in general
There is nothing difficult in that. A function is a set of pairs. Two sets
are equal when contain same elements.
> X and Y above of course may contain different state information as they
> run but that's all related to the operation of execution; it doesn't
> distinguish their "task values."
Of course it does. For example: it can happen that X'Terminated /=
Y'Terminated.
>> Because the literal 2 [of type Integer] denotes the same value in all
>> contexts. But X, Y : Driver clearly do not do that. If X and Y are not
>> equivalent how they could have the same value?
>
> I guess this is where we disagree. To me X and Y do denote the same value
> in all contexts; they are equivalent.
They are evidently not, which can be easily demonstrated by presenting a
program which would yield different results depending on whether X or Y is
used.
>> Either the values are different or else you need to bring some other
>> stuff beyond types, values and operations into the picture.
>
> Are you referring to the execution state here?
It is your concept, I am only giving you enough rope to hang yourselves...
> To my mind that dynamic
> information is just part of the operation of execution. It's necessary to
> make that operation work but, yes, I agree that it is a separate matter
> from the types and values, etc.
Which means that your model is inadequate to describe the way programs
work, and more generally to programming.
>>>> e : constant :=
>>>> 2.71828_18284_59045_23536_02874_71352_66249_77572_47093_69996;
>>>
>>> As I understand it, 'e' has type Universal_Float and the 2.718... is a
>>> value inhabiting that type. I guess I don't understand what point you are
>>> making here.
>>
>> The point is about the value of e. You said that when declared as I did, it
>> has no significance, just a random pattern of bits. Do I interpret you
>> correctly? Does this same logic apply to e of Ada.Numerics? If not where is
>> a difference?
>
> We're talking about two different 'e's here. In the first case 'e' was an
> enumeration literal. The type in that example was suggestively named
> Transcendental_Constants (or something like that... I forget exactly), but
> any connection between 'e' and the mathematical value of e was purely in
> the mind of the programmer.
How Universal_Integer is different?
> In Ada terms 'e' was a value of that type but
> nothing beyond that. That's what I meant by it not having any
> significance.
>
> In the second case 'e' is a named number bound to a value in the
> Universal_Float type that is clearly intended to be the mathematical e...
How it is more "clearly intended" than enumeration 'e'?
Note that neither is mathematical e. They *model* e = as you said "purely
in the mind of the programmer." This is what value is, an idea behind a
computational state.
> at least to the closest degree permitted by the available values in that
> type (I guess in this case it's really limited by the amount of space the
> implementer wants to use when writing the declaration. Am I correct in
> saying that Universal_Float has infinite precision?)
It has an indefinite precision.
> I suppose I don't understand the point you were trying to make originally
> with the enumeration type. There 'e' was a value of the specified type.
> Was that it?
The value of e was meant to represent the transcendental number e. The type
was meant to model real numbers. Similarly Ada.Numerics e is meant to
represent e. And Universal_Real is meant to model real numbers. e is not
Ada term. It is a term of mathematical analysis. Neither type is real, they
are only models of.
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
^ permalink raw reply [relevance 4%]
* Re: Seeking for papers about tagged types vs access to subprograms
2013-05-16 12:20 4% ` Dmitry A. Kazakov
@ 2013-05-16 13:10 0% ` Peter C. Chapin
2013-05-16 13:54 4% ` Dmitry A. Kazakov
0 siblings, 1 reply; 200+ results
From: Peter C. Chapin @ 2013-05-16 13:10 UTC (permalink / raw)
On Thu, 16 May 2013, Dmitry A. Kazakov wrote:
>>> So,
>>>
>>> X, Y : Driver;
>>>
>>> have same values?
>>
>> Yes, I would say so.
>
> Really? X is an *equivalent* of Y?
Sure. If it were allowed the expression 'X = Y' should return True. I
realize that equivalence of functions is a difficult concept in general (I
believe it's undecidable to determine if two functions f_1 and f_2 are
equivalent even if you can see the source code of both) but here since the
code for both X and Y is, in fact, the very same program text, it seems
clear that they are equivalent.
X and Y above of course may contain different state information as they
run but that's all related to the operation of execution; it doesn't
distinguish their "task values."
These concepts are all quite straightforward, it seems to me, in the
context of functional languages. Of course Ada isn't a functional language
and it has side effects, etc, so things do get a bit messier. I still
contend, however, that the basic ideas still... er... apply.
> Because the literal 2 [of type Integer] denotes the same value in all
> contexts. But X, Y : Driver clearly do not do that. If X and Y are not
> equivalent how they could have the same value?
I guess this is where we disagree. To me X and Y do denote the same value
in all contexts; they are equivalent.
> Either the values are different or else you need to bring some other
> stuff beyond types, values and operations into the picture.
Are you referring to the execution state here? To my mind that dynamic
information is just part of the operation of execution. It's necessary to
make that operation work but, yes, I agree that it is a separate matter
from the types and values, etc.
Modeling state in a clean way is slippery business. You might be able to
bring it into the context of this discussion by treating the state of each
task as a kind of mutable parameter to the task. As such there could be an
implicit type for that parameter... some kind of record type, etc... but
it does get messy.
>>> e : constant :=
>>> 2.71828_18284_59045_23536_02874_71352_66249_77572_47093_69996;
>>
>> As I understand it, 'e' has type Universal_Float and the 2.718... is a
>> value inhabiting that type. I guess I don't understand what point you are
>> making here.
>
> The point is about the value of e. You said that when declared as I did, it
> has no significance, just a random pattern of bits. Do I interpret you
> correctly? Does this same logic apply to e of Ada.Numerics? If not where is
> a difference?
We're talking about two different 'e's here. In the first case 'e' was an
enumeration literal. The type in that example was suggestively named
Transcendental_Constants (or something like that... I forget exactly), but
any connection between 'e' and the mathematical value of e was purely in
the mind of the programmer. In Ada terms 'e' was a value of that type but
nothing beyond that. That's what I meant by it not having any
significance.
In the second case 'e' is a named number bound to a value in the
Universal_Float type that is clearly intended to be the mathematical e...
at least to the closest degree permitted by the available values in that
type (I guess in this case it's really limited by the amount of space the
implementer wants to use when writing the declaration. Am I correct in
saying that Universal_Float has infinite precision?)
I suppose I don't understand the point you were trying to make originally
with the enumeration type. There 'e' was a value of the specified type.
Was that it?
Peter
^ permalink raw reply [relevance 0%]
* Re: Seeking for papers about tagged types vs access to subprograms
2013-05-16 11:31 0% ` Peter C. Chapin
@ 2013-05-16 12:20 4% ` Dmitry A. Kazakov
2013-05-16 13:10 0% ` Peter C. Chapin
0 siblings, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2013-05-16 12:20 UTC (permalink / raw)
On Thu, 16 May 2013 07:31:58 -0400, Peter C. Chapin wrote:
> On Thu, 16 May 2013, Dmitry A. Kazakov wrote:
>
>>> Weren't we talking about "value" as a programming language term?
>>
>> You consider value being a language term. I objected, pointing out that
>> value is the meaning of some program state, the meaning which is always
>> outside the language and from the problem space. The only case when a
>> value can be an Ada term is when the program is an Ada compiler.
>>
>>> I understand that to mean "value" as something used by people when
>>> talking about programming languages.
>>
>> Yes.
>
> You said earlier, "value is the meaning of some program state..." So
> "value" is, indeed, a term used when discussing programming languages.
> That was my original contention. Recall that we were talking about types
> and values and their relationship. I again return to my original
> statement: a type is two sets, a set of values and a set of operations.
> Are you disagreeing with that?
No. Why should I?
>> So,
>>
>> X, Y : Driver;
>>
>> have same values?
>
> Yes, I would say so.
Really? X is an *equivalent* of Y?
>> You seem to confuse value for its representation. The value of a task
>> type is not even computable, or the value of clock. The representation
>> of a task value might be a combination of some code, TCB, the state of
>> system queues etc.
>
> I actually don't think I'm all that confused. I borrow concepts that are
> standard in functional languages where functions are, indeed, first class
> values. There a function's value is its (source) code. Two different
> instances of the same function represent the same value just as two
> different instances of the integer literal "2" represent the same value.
Because the literal 2 [of type Integer] denotes the same value in all
contexts. But X, Y : Driver clearly do not do that. If X and Y are not
equivalent how they could have the same value? Either the values are
different or else you need to bring some other stuff beyond types, values
and operations into the picture.
>> And what significance has Ada.Numerics'
>>
>> e : constant :=
>> 2.71828_18284_59045_23536_02874_71352_66249_77572_47093_69996;
>
> As I understand it, 'e' has type Universal_Float and the 2.718... is a
> value inhabiting that type. I guess I don't understand what point you are
> making here.
The point is about the value of e. You said that when declared as I did, it
has no significance, just a random pattern of bits. Do I interpret you
correctly? Does this same logic apply to e of Ada.Numerics? If not where is
a difference? If you think that values should have "significance", then
what is significance? Why enumeration value does not have it and
Universal_Integer does?
P.S. What you call "significance" is the value. What you call "value" is a
representation.
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
^ permalink raw reply [relevance 4%]
* Re: Seeking for papers about tagged types vs access to subprograms
2013-05-15 22:08 4% ` Dmitry A. Kazakov
@ 2013-05-16 11:31 0% ` Peter C. Chapin
2013-05-16 12:20 4% ` Dmitry A. Kazakov
0 siblings, 1 reply; 200+ results
From: Peter C. Chapin @ 2013-05-16 11:31 UTC (permalink / raw)
On Thu, 16 May 2013, Dmitry A. Kazakov wrote:
>> Weren't we talking about "value" as a programming language term?
>
> You consider value being a language term. I objected, pointing out that
> value is the meaning of some program state, the meaning which is always
> outside the language and from the problem space. The only case when a
> value can be an Ada term is when the program is an Ada compiler.
>
>> I understand that to mean "value" as something used by people when
>> talking about programming languages.
>
> Yes.
You said earlier, "value is the meaning of some program state..." So
"value" is, indeed, a term used when discussing programming languages.
That was my original contention. Recall that we were talking about types
and values and their relationship. I again return to my original
statement: a type is two sets, a set of values and a set of operations.
Are you disagreeing with that? I honestly can't tell.
> So,
>
> X, Y : Driver;
>
> have same values?
Yes, I would say so.
> You seem to confuse value for its representation. The value of a task
> type is not even computable, or the value of clock. The representation
> of a task value might be a combination of some code, TCB, the state of
> system queues etc.
I actually don't think I'm all that confused. I borrow concepts that are
standard in functional languages where functions are, indeed, first class
values. There a function's value is its (source) code. Two different
instances of the same function represent the same value just as two
different instances of the integer literal "2" represent the same value.
The machine representation of a function---how it is converted to
executable form---is at the compiler's discretion, of course. In some
languages function types have only a single operation, that of
"application" (calling). Some of the items you mentioned above exist to
support the execution of that operation; they are not part of the value.
Ada tasks are not quite like functions but conceptually there are
similarities. One important limitation of Ada is that every task type is
inhabited with only a single value. It isn't possible to create multiple
task bodies behind a task type definition. In contrast consider:
function F1(X : Integer) return String;
function F2(X : Integer) return String;
Here F1 and F2 have the same "function type." They are two different
values that inhabit that type just as "2" and "3" are two different values
inhabiting Integer.
But if you say
task type T is
...
end T;
You can only write one body to go with the type. Every instance of type T
thus has the same value---the type has only one value.
This limitation doesn't change the concepts, it just reflects a limitation
of Ada. In the more general case there would be "task operators" that
would allow you to compose tasks to make new tasks (higher order tasks?)
and you would be able to store different tasks into the same variable of
task type provided all the tasks had the same type (but possibly different
bodies). Of course this language isn't Ada.
That said, the Ada 2005 features of synchronized and protected interfaces
are moving into this terrian. A full theoretical accounting of Ada task
types would be a very interesting exercise (has it been done?).
> And what significance has Ada.Numerics'
>
> e : constant :=
> 2.71828_18284_59045_23536_02874_71352_66249_77572_47093_69996;
As I understand it, 'e' has type Universal_Float and the 2.718... is a
value inhabiting that type. I guess I don't understand what point you are
making here. I apologize if I cut too much context.
Peter
^ permalink raw reply [relevance 0%]
* Re: Seeking for papers about tagged types vs access to subprograms
@ 2013-05-15 22:08 4% ` Dmitry A. Kazakov
2013-05-16 11:31 0% ` Peter C. Chapin
0 siblings, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2013-05-15 22:08 UTC (permalink / raw)
On Wed, 15 May 2013 17:12:09 -0400, Peter C. Chapin wrote:
> On Wed, 15 May 2013, Dmitry A. Kazakov wrote:
>
>>> A type is a pair of sets: a set of values and a set of operations defined
>>> over those values (for example as functions taking items from the first
>>> set as a parameter). Either set can be empty. In any case "value" is most
>>> certainly a programming language term.
>>
>> type Employee is ...;
>>
>> How is employee a language term?
>
> Weren't we talking about "value" as a programming language term?
You consider value being a language term. I objected, pointing out that
value is the meaning of some program state, the meaning which is always
outside the language and from the problem space. The only case when a value
can be an Ada term is when the program is an Ada compiler.
> I
> understand that to mean "value" as something used by people when talking
> about programming languages.
Yes.
> "Employees" is just a name in some program...
> and specifically the name of a type. I don't follow what this has to do
> with a discussion about values.
The type Employee has values denoting employees of some business in some
Ada program.
>> task type Driver is ...;
>>
>> Show me an RM section which defines the values of this type.
>
> The values of a task type are the code fragments that implement the
> task. Here I'm speaking in general terms, of course.
So,
X, Y : Driver;
have same values? You seem to confuse value for its representation. The
value of a task type is not even computable, or the value of clock. The
representation of a task value might be a combination of some code, TCB,
the state of system queues etc.
>> And the simplest possible example why the language has nothing to do with
>> values is this:
>>
>> type Some_Transcendental_Numbers is (e, Pi, Euler);
>>
>> What is the value of e?
>
> Some_Transcendental_Numbers is an enumeration type. One of it's values is
> 'e'. There is no significance to 'e' other than that. At least at the
> level of types.
And what significance has Ada.Numerics'
e : constant :=
2.71828_18284_59045_23536_02874_71352_66249_77572_47093_69996;
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
^ permalink raw reply [relevance 4%]
* Interresting difference in Normal-Returns/Expression-Functions and Extended-Returns.
@ 2013-04-22 18:27 5% Shark8
0 siblings, 0 replies; 200+ results
From: Shark8 @ 2013-04-22 18:27 UTC (permalink / raw)
I recently ran into unexpected behavior in the differences between a normal return and an extended return [in GNAT]: namely an extended return used to generate items in an array of tasks will *ALWAYS* execute in a sequential manner whereas the array generated with an expression-function or normal return is executed simultaneously.
Is there some subtle difference in the extended return that I'm unaware of? (Is this a bug?)
--------------------
-- Experiment.adb --
--------------------
Pragma Ada_2012;
With
Ada.Text_IO,
Ada.Numerics.Float_Random
;
Procedure Experiment is
-----------------------------------------------------
-- RNG; This sets up random numbers for durations. --
-----------------------------------------------------
Package RNG is
Function Random Return Duration;
Private
Use Ada.Numerics.Float_Random;
G : Generator;
Function Random Return Duration is
( Duration( Random(G) ) );
End RNG;
Package Body RNG is
Begin
Ada.Numerics.Float_Random.Reset( G );
End RNG;
--------------------------------------------------
-- Resource; Protected object handling Text-IO. --
--------------------------------------------------
protected Resource is
procedure Write( Input : In String );
procedure New_Line;
private
end Resource;
protected body Resource is
procedure Write( Input : In String ) is
begin
Ada.Text_IO.Put_Line( Input );
end Write;
Procedure New_Line is begin Write(""); end New_Line;
end Resource;
---------------------------------------------------------
-- Testing; This is the task-type we are playing with. --
---------------------------------------------------------
Task Type Testing( Text : Not Null Access Constant String ) is
end Testing;
Task Body Testing is
D : Duration := RNG.Random; -- Get a random duration.
Begin
delay D; -- Delay for that duration.
-- Then print the Text for the task as well as the Delay.
Resource.Write( Text.ALL & ASCII.HT & Duration'Image(D) );
End Testing;
-- Make; these functions make an access-to-tasks for arrays.
-- Note: these should all be equivelant.
Function Make_EF(Input : in String) Return Not Null Access Testing is
( New Testing( Text => New String'(Input) ) );
Function Make_ER(Input : in String) Return Not Null Access Testing is
begin
Return Result : Not Null Access Testing:= New Testing(New String'(Input));
End Make_ER;
Function Make_NR(Input : in String) Return Not Null Access Testing is
begin
Return New Testing(New String'(Input));
End Make_NR;
Begin
Resource.Write("TEST_1:"& ASCII.HT &"Expression Function");
TEST_1:
declare
Function Make(Input : in String) Return Not Null Access Testing
Renames Make_EF;
P : Constant Array (Positive Range <>) of
Not Null Access Constant Testing:=
( Make("Bob"), Make("Steve"), Make("Dave"), Make("Joey") );
begin
null;
end TEST_1;
Resource.New_Line;
Resource.Write("TEST_2:"& ASCII.HT &"Normal Return Function");
TEST_2:
declare
Function Make(Input : in String) Return Not Null Access Testing
Renames Make_NR;
P : Constant Array (Positive Range <>) of
Not Null Access Constant Testing:=
( Make("Bob"), Make("Steve"), Make("Dave"), Make("Joey") );
begin
null;
end TEST_2;
Resource.New_Line;
Resource.Write("TEST_3:"& ASCII.HT &"Extended Return Function");
TEST_3:
declare
Function Make(Input : in String) Return Not Null Access Testing
Renames Make_ER;
P : Constant Array (Positive Range <>) of
Not Null Access Constant Testing:=
( Make("Bob"), Make("Steve"), Make("Dave"), Make("Joey") );
begin
null;
end TEST_3;
Resource.New_Line;
Resource.Write( "Terminating." );
End Experiment;
^ permalink raw reply [relevance 5%]
* Pure vs. Pure; aspect vs. pragma.
@ 2013-03-29 0:32 5% Shark8
0 siblings, 0 replies; 200+ results
From: Shark8 @ 2013-03-29 0:32 UTC (permalink / raw)
In the Ada 2012 rationale it says:
> A number of existing pragmas are paralleled by aspect specifications but the pragmas are not made obsolete. Examples are the pragmas relating to packages such as Pure, Preelaborate, Elaborate_Body and so on.
>
> Thus we can write either of
>
> package P is
> pragma Pure(P);
> end P;
>
> or
>
> package P
> with Pure is
> end P;
So they should be equivalent; this, however, is not so in GNAT-2012.
Example:
-----------------------------------------------
-- Test.adb
Pragma Ada_2012;
Pragma Assertion_Policy( Check );
With
some_function,
subtype_definitions,
subtype_definitions2,
Ada.Text_IO;
Procedure Test is
Function F( Parameter : Integer ) Return Integer renames some_function;
Begin
Ada.Text_IO.Put_Line("Starting Test:");
declare
Generic
Type S is (<>);
With Function Image( Item: S ) Return String is S'Image;
Package Metric is
First : Constant S := S'First;
Last : Constant S := S'Last;
Function Range_String(Name : String) Return String is
(Name & " is Range" & First'Img & " .." & Last'Img);
End Metric;
-- Swap out these definitione to see the differences.
Package S is new subtype_definitions;
-- Package S is new subtype_definitions2(f(1), f(2), f(11));
Package M1 is new Metric( S.S1 );
Package M2 is new Metric( S.S2 );
Package M3 is new Metric( S.S3 );
Use Ada.Text_IO;
begin
Put_Line( M1.Range_String( "S1" ) );
Put_Line( M2.Range_String( "S2" ) );
Put_Line( M3.Range_String( "S3" ) );
end;
Ada.Text_IO.Put_Line("Testing complete.");
End Test;
-----------------------------------------------
-- some_function.adb
With Ada.Numerics.Discrete_Random;
Function Some_Function( Parameter : Integer ) Return Integer is
Subtype K is Positive Range 64..1024;
Package RNG_Pkg is new Ada.Numerics.Discrete_Random(Result_Subtype => K);
RNG : RNG_Pkg.Generator;
begin
-- There is actually another function here importing glGetIntegerv,
-- executing it, and returning the result in 'Result'.
Return Result : Integer do
for Index in 1..Parameter loop
Result:= RNG_Pkg.Random(RNG);
end loop;
end return;
end Some_Function;
-----------------------------------------------
-- subtype_definitions.ads
With some_Function;
generic
package subtype_definitions with Pure is
-- Cannot uncomment.
-- Pragma Pure;
subtype S1 is Integer Range
0 .. some_function(1);
subtype S2 is Integer Range
0 .. some_function(2);
subtype S3 is Integer Range
0 .. some_function(11);
end subtype_definitions;
-----------------------------------------------
-- subtype_definitions2.adb
generic
L1 : Integer;
L2 : Integer;
L3 : Integer;
package subtype_definitions2 with Pure is
Pragma Pure;
subtype S1 is Integer Range
0 .. L1;
subtype S2 is Integer Range
0 .. L2;
subtype S3 is Integer Range
0 .. L3;
end subtype_definitions2;
---------------------------------------------------
I ran into this when restructuring my open-gl library; the idea being that I can have the object-enumerations (lights, buffers, etc) definitions dynamically defined at instantiation on the target computer -- these enumerations have certain mandatory minimums [on the upper bound] and those, it seems, are what the open-gl bindings I've looked at [mostly C/C++] seem to embrace... but it seems a bit limiting to do that in Ada when we have subtypes [which can be dynamically set].
{Of course subprograms taking those enumerations should have parameters of those subtypes; leading me to think generic-packages would be the best way to address this.}
^ permalink raw reply [relevance 5%]
* Re: Is this expected behavior or not
@ 2013-03-16 16:55 5% ` Shark8
0 siblings, 0 replies; 200+ results
From: Shark8 @ 2013-03-16 16:55 UTC (permalink / raw)
Cc: mailbox
On Saturday, March 16, 2013 1:41:27 AM UTC-6, Dmitry A. Kazakov wrote:
> On Fri, 15 Mar 2013 22:52:02 -0700 (PDT), Shark8 wrote:
>
> > True; but there could be some more interesting cases, say, for Ada 2020.
> > Something like:
> >
> > Abstract Type UNIVERSAL_STRING(Element : UNIVERSAL_CHARACTER) is
> > Array(Positive Range <>) of Element'Type;
>
> That would not work. I presume that here you want to create a root type for
> the class of string types and get at the members of the class (specific
> types like Wide_String) using a constraint. The problem is that string
> types must have different representations. The mechanism of constraining
> does not support.
Kind of, but not really; I'm thinking a sort of combination of generics and classes (in the general sense, not the OOP-sense): a way to specify a general behavior for a type-class. (i.e. having the ability to fully-specify things like attributes [not really shown in this example].)
> Thus either subtypes will have same representation or you
> won't have a class.
I'm thinking of it more in the terms of generic operations: independent of representation.
> Another problem is that string types must have more
> than one interface to deal with UTF-8 etc. An UTF-8 string is *both* an
> array of Wide_Wide_Character (= Unicode code points) and an array or
> sequence of Character (octets).
Ah, things get tricky here; Unicode is kind of a bear when you consider 'characters' because its codepoints aren't necessarily characters. An example would be the so-called "combining characters" which you can use for things like accents or ZALGO-text. (See these, respectively: http://en.wikipedia.org/wiki/Combining_character and, http://eeemo.net/ )
An important implication of this is that string search/manipulation becomes MUCH more complex. (`+a = à) means that you now have to search for multiple possibilities when your target is "à" -> the single-glyph code-point, or the combining-character points... and that's not taking into consideration whether you should consider a & à & (a+diacritic) to be the same or unique entities -- and casing is another combinatorial factor.
It would be a big mistake to assume character = code-point when dealing with Unicode.
> An UTF-16 string is an array of Wide_Wide_Character and an array of Wide_String.
UTF-16 is perhaps the worst possible encoding you can have for Unicode. With UTF-8 you don't need to worry about byte-order (everything's sequential) and with UTF-32 you don't need to decode the information (each element *IS* a code-point)... but UTF-16 offers neither of these.
------------------------------------------------------
I guess what I'm trying to say is that if we did it right, we could modify/expand the type-system so that something like UNIVERSAL_INTEGER could be made/explicitly-specified. (And if done extremely well, something like UNIVERSAL_STRING where perhaps the only thing differentiating the strings would be the 'instantiation' with their proper character-type* and manipulation-functions.) -- GNAT already has the 'Universal_Literal_String which works in either of the following lines:
Ada.Wide_Wide_Text_IO.Put_Line( Ada.Numerics.Pi'Universal_Literal_String )
Ada.Text_IO.Put_Line( Ada.Numerics.Pi'Universal_Literal_String )
In any case; I think it worth considering not just outward/downward expansion of the language, but inward/upward [unification] as well.
^ permalink raw reply [relevance 5%]
* Re: Parallel_Simulation
2013-02-25 18:30 0% ` Parallel_Simulation John B. Matthews
@ 2013-02-26 7:13 0% ` Vincent LAFAGE
0 siblings, 0 replies; 200+ results
From: Vincent LAFAGE @ 2013-02-26 7:13 UTC (permalink / raw)
Le 25/02/2013 19:30, John B. Matthews a écrit :
> In article <kgg6b2$kma$1@ccpntc8.in2p3.fr>,
> Vincent LAFAGE <lafage@ipno.in2p3.fr> wrote:
>
>> Le 25/02/2013 13:40, John B. Matthews a écrit :
>>> In article <kgfdsp$tb0$1@ccpntc8.in2p3.fr>,
>>> Vincent LAFAGE <lafage@ipno.in2p3.fr> wrote:
>>>
>>>> I am interested in MonteCarlo simulation and I had translated a
>>>> former F77 code to Ada with success, with the goal of
>>>> parallelizing it, but one part in the algorithm still resists
>>>> parallelization: the random number generator. I need the different
>>>> worker to rely on independant random number generators.
>>>>
>>>> Then I found a precious example in
>>>> RM-A-5-2 59., 60., 61.
>>>> that compiles smoothly.
>>>>
>>>> I will now attempt to check the independance of the sequence
>>>> generated by each thread. But this kind of check is always more
>>>> subtle than expected.
>>>>
>>>> I wonder whether there is a statement about the independance of
>>>> such generator, in particular in the gnat implementation?
>>>
>>> You should check your implementation's required documentation and
>>> any statements on implementation advice. For example, GNAT includes
>>> a comment in Ada.Numerics.Float_Random.ads, and the GNAT Reference
>>> Manual says, "The generator period is sufficiently long for the
>>> first condition here [A.5.2(47)] to hold true."
>>
>> Thanks for the advice, but the particular doesn't exactly fit my
>> question. I understand that the sequence is long enough. But
>> different seeds will in the end be different starting points along
>> the same sequence (well, at least for congruential generators, I
>> still have to confirm it for Mersenne Twister algorithm that is
>> used). And this would in turn lead to fine correlations between the
>> sequences.
>>
>> The best statement I have found until now is in gnat_rm-4.6.info:
>>
>> *67*. The minimum time interval between calls to the time-dependent
>> Reset procedure that are guaranteed to initiate different random
>> number sequences. See A.5.2(45).
>> The minimum period between reset calls to guarantee distinct
>> series of random numbers is one microsecond.
>>
>> So I need to assert the delay between the reset of each worker in
>> RM-A-5-2 60 to be sure that there is at least one microsecond.
>
> IIUC, the example in A.5.2(60) uses the version of Reset that is _not_
> time-dependent; it initializes each Worker's generator to "a state
> denoted by a single integer." As long as you're not using the
> time-dependent version, I don't see how the minimum period would come
> into play.
Indeed.
>> Would you think of another way?
>
> If you Reset a single instance of Discrete_Random in a time-dependent
> way and use it to generate each Worker's Initiator, as suggested in
> A.5.2(61), I don't see much chance of correlation.
Thank you for your guidance and detailled answer!
Vincent
^ permalink raw reply [relevance 0%]
* Re: Parallel_Simulation
2013-02-25 17:17 0% ` Parallel_Simulation Vincent LAFAGE
2013-02-25 18:30 0% ` Parallel_Simulation John B. Matthews
@ 2013-02-26 7:09 0% ` Vincent LAFAGE
1 sibling, 0 replies; 200+ results
From: Vincent LAFAGE @ 2013-02-26 7:09 UTC (permalink / raw)
Le 25/02/2013 18:17, Vincent LAFAGE a écrit :
> Le 25/02/2013 13:40, John B. Matthews a écrit :
>> In article <kgfdsp$tb0$1@ccpntc8.in2p3.fr>,
>> Vincent LAFAGE <lafage@ipno.in2p3.fr> wrote:
>>
>>> I am interested in MonteCarlo simulation and I had translated a
>>> former F77 code to Ada with success, with the goal of parallelizing
>>> it, but one part in the algorithm still resists parallelization: the
>>> random number generator. I need the different worker to rely on
>>> independant random number generators.
>>>
>>> Then I found a precious example in
>>> RM-A-5-2 59., 60., 61.
>>> that compiles smoothly.
>>>
>>> I will now attempt to check the independance of the sequence
>>> generated by each thread. But this kind of check is always more
>>> subtle than expected.
>>>
>>> I wonder whether there is a statement about the independance of such
>>> generator, in particular in the gnat implementation?
>>
>> You should check your implementation's required documentation and any
>> statements on implementation advice. For example, GNAT includes a
>> comment in Ada.Numerics.Float_Random.ads, and the GNAT Reference Manual
>> says, "The generator period is sufficiently long for the first condition
>> here [A.5.2(47)] to hold true."
>
> Thanks for the advice,
> but the particular doesn't exactly fit my question.
Ooups...
Sorry I hastened to answer while I had not read carefully enough
A.5.2(47)
47. If the generator period is sufficiently long in relation to the
number of distinct initiator values, then each possible value of
Initiator passed to Reset should initiate a sequence of random
numbers that does not, in a practical sense, overlap the sequence
initiated by any other value. If this is not possible, then the
mapping between initiator values and generator states should be a
rapidly varying function of the initiator value.
I see the statement, but while Mersenne Twister algorithms provides
very, very long period (2^19937?), I would appreciate order of
magnitudes of the subperiods.
I guess I have to test,
And read much more m(__)m
Best regards
> I understand that the sequence is long enough.
> But different seeds will in the end be different starting points along
> the same sequence (well, at least for congruential generators, I still
> have to confirm it for Mersenne Twister algorithm that is used).
> And this would in turn lead to fine correlations between the sequences.
>
> The best statement I have found until now is in gnat_rm-4.6.info:
>
> *67*. The minimum time interval between calls to the time-dependent
> Reset procedure that are guaranteed to initiate different random number
> sequences. See A.5.2(45).
> The minimum period between reset calls to guarantee distinct series
> of random numbers is one microsecond.
>
> So I need to assert the delay between the reset of each worker in
> RM-A-5-2 60.
> to be sure that there is at least one microsecond.
>
> Would you think of another way?
>
> Best regards
> Vincent
^ permalink raw reply [relevance 0%]
* Re: Parallel_Simulation
2013-02-25 17:17 0% ` Parallel_Simulation Vincent LAFAGE
@ 2013-02-25 18:30 0% ` John B. Matthews
2013-02-26 7:13 0% ` Parallel_Simulation Vincent LAFAGE
2013-02-26 7:09 0% ` Parallel_Simulation Vincent LAFAGE
1 sibling, 1 reply; 200+ results
From: John B. Matthews @ 2013-02-25 18:30 UTC (permalink / raw)
In article <kgg6b2$kma$1@ccpntc8.in2p3.fr>,
Vincent LAFAGE <lafage@ipno.in2p3.fr> wrote:
> Le 25/02/2013 13:40, John B. Matthews a écrit :
> > In article <kgfdsp$tb0$1@ccpntc8.in2p3.fr>,
> > Vincent LAFAGE <lafage@ipno.in2p3.fr> wrote:
> >
> >> I am interested in MonteCarlo simulation and I had translated a
> >> former F77 code to Ada with success, with the goal of
> >> parallelizing it, but one part in the algorithm still resists
> >> parallelization: the random number generator. I need the different
> >> worker to rely on independant random number generators.
> >>
> >> Then I found a precious example in
> >> RM-A-5-2 59., 60., 61.
> >> that compiles smoothly.
> >>
> >> I will now attempt to check the independance of the sequence
> >> generated by each thread. But this kind of check is always more
> >> subtle than expected.
> >>
> >> I wonder whether there is a statement about the independance of
> >> such generator, in particular in the gnat implementation?
> >
> > You should check your implementation's required documentation and
> > any statements on implementation advice. For example, GNAT includes
> > a comment in Ada.Numerics.Float_Random.ads, and the GNAT Reference
> > Manual says, "The generator period is sufficiently long for the
> > first condition here [A.5.2(47)] to hold true."
>
> Thanks for the advice, but the particular doesn't exactly fit my
> question. I understand that the sequence is long enough. But
> different seeds will in the end be different starting points along
> the same sequence (well, at least for congruential generators, I
> still have to confirm it for Mersenne Twister algorithm that is
> used). And this would in turn lead to fine correlations between the
> sequences.
>
> The best statement I have found until now is in gnat_rm-4.6.info:
>
> *67*. The minimum time interval between calls to the time-dependent
> Reset procedure that are guaranteed to initiate different random
> number sequences. See A.5.2(45).
> The minimum period between reset calls to guarantee distinct
> series of random numbers is one microsecond.
>
> So I need to assert the delay between the reset of each worker in
> RM-A-5-2 60 to be sure that there is at least one microsecond.
IIUC, the example in A.5.2(60) uses the version of Reset that is _not_
time-dependent; it initializes each Worker's generator to "a state
denoted by a single integer." As long as you're not using the
time-dependent version, I don't see how the minimum period would come
into play.
> Would you think of another way?
If you Reset a single instance of Discrete_Random in a time-dependent
way and use it to generate each Worker's Initiator, as suggested in
A.5.2(61), I don't see much chance of correlation.
--
John B. Matthews
trashgod at gmail dot com
<http://sites.google.com/site/drjohnbmatthews>
^ permalink raw reply [relevance 0%]
* Re: Parallel_Simulation
2013-02-25 12:40 5% ` Parallel_Simulation John B. Matthews
@ 2013-02-25 17:17 0% ` Vincent LAFAGE
2013-02-25 18:30 0% ` Parallel_Simulation John B. Matthews
2013-02-26 7:09 0% ` Parallel_Simulation Vincent LAFAGE
0 siblings, 2 replies; 200+ results
From: Vincent LAFAGE @ 2013-02-25 17:17 UTC (permalink / raw)
Le 25/02/2013 13:40, John B. Matthews a écrit :
> In article <kgfdsp$tb0$1@ccpntc8.in2p3.fr>,
> Vincent LAFAGE <lafage@ipno.in2p3.fr> wrote:
>
>> I am interested in MonteCarlo simulation and I had translated a
>> former F77 code to Ada with success, with the goal of parallelizing
>> it, but one part in the algorithm still resists parallelization: the
>> random number generator. I need the different worker to rely on
>> independant random number generators.
>>
>> Then I found a precious example in
>> RM-A-5-2 59., 60., 61.
>> that compiles smoothly.
>>
>> I will now attempt to check the independance of the sequence
>> generated by each thread. But this kind of check is always more
>> subtle than expected.
>>
>> I wonder whether there is a statement about the independance of such
>> generator, in particular in the gnat implementation?
>
> You should check your implementation's required documentation and any
> statements on implementation advice. For example, GNAT includes a
> comment in Ada.Numerics.Float_Random.ads, and the GNAT Reference Manual
> says, "The generator period is sufficiently long for the first condition
> here [A.5.2(47)] to hold true."
Thanks for the advice,
but the particular doesn't exactly fit my question.
I understand that the sequence is long enough.
But different seeds will in the end be different starting points along
the same sequence (well, at least for congruential generators, I still
have to confirm it for Mersenne Twister algorithm that is used).
And this would in turn lead to fine correlations between the sequences.
The best statement I have found until now is in gnat_rm-4.6.info:
*67*. The minimum time interval between calls to the time-dependent
Reset procedure that are guaranteed to initiate different random number
sequences. See A.5.2(45).
The minimum period between reset calls to guarantee distinct series
of random numbers is one microsecond.
So I need to assert the delay between the reset of each worker in
RM-A-5-2 60.
to be sure that there is at least one microsecond.
Would you think of another way?
Best regards
Vincent
^ permalink raw reply [relevance 0%]
* Re: Parallel_Simulation
@ 2013-02-25 12:40 5% ` John B. Matthews
2013-02-25 17:17 0% ` Parallel_Simulation Vincent LAFAGE
0 siblings, 1 reply; 200+ results
From: John B. Matthews @ 2013-02-25 12:40 UTC (permalink / raw)
In article <kgfdsp$tb0$1@ccpntc8.in2p3.fr>,
Vincent LAFAGE <lafage@ipno.in2p3.fr> wrote:
> I am interested in MonteCarlo simulation and I had translated a
> former F77 code to Ada with success, with the goal of parallelizing
> it, but one part in the algorithm still resists parallelization: the
> random number generator. I need the different worker to rely on
> independant random number generators.
>
> Then I found a precious example in
> RM-A-5-2 59., 60., 61.
> that compiles smoothly.
>
> I will now attempt to check the independance of the sequence
> generated by each thread. But this kind of check is always more
> subtle than expected.
>
> I wonder whether there is a statement about the independance of such
> generator, in particular in the gnat implementation?
You should check your implementation's required documentation and any
statements on implementation advice. For example, GNAT includes a
comment in Ada.Numerics.Float_Random.ads, and the GNAT Reference Manual
says, "The generator period is sufficiently long for the first condition
here [A.5.2(47)] to hold true."
--
John B. Matthews
trashgod at gmail dot com
<http://sites.google.com/site/drjohnbmatthews>
^ permalink raw reply [relevance 5%]
* Re: Announce: Updated version of ada-lapack on sourceforge
2013-01-06 0:46 5% Announce: Updated version of ada-lapack on sourceforge Leo Brewin
@ 2013-01-07 21:57 0% ` Jerry
0 siblings, 0 replies; 200+ results
From: Jerry @ 2013-01-07 21:57 UTC (permalink / raw)
On Saturday, January 5, 2013 5:46:24 PM UTC-7, Leo Brewin wrote:
> Greetings,
> I've updated the ada-lapack library on sourceforge.
> The most significant change since the initial release is the change in the
> pacakge spec to use the standard real and complex arrays provided by Ada.Numerics.
> The package now conforms with Ada Annex G.3.
> New procedues in this release are
>
> gesdd and gesvd (implementing dgesdd, dgesvd, zgesdd and zgesvd).
> Minor housekeeping has also be done to the code base.
>
> You can find the code at
> http://sourceforge.net/projects/ada-lapack/
>
> Comments, opinions, suggestions etc. are most welcome.
>
> Cheers,
>
> Leo
Thanks, Leo. G.3 compatibility is _huge_!
Jerry
^ permalink raw reply [relevance 0%]
* Announce: Updated version of ada-lapack on sourceforge
@ 2013-01-06 0:46 5% Leo Brewin
2013-01-07 21:57 0% ` Jerry
0 siblings, 1 reply; 200+ results
From: Leo Brewin @ 2013-01-06 0:46 UTC (permalink / raw)
Greetings,
I've updated the ada-lapack library on sourceforge.
The most significant change since the initial release is the change in the
pacakge spec to use the standard real and complex arrays provided by Ada.Numerics.
The package now conforms with Ada Annex G.3.
New procedues in this release are
gesdd and gesvd (implementing dgesdd, dgesvd, zgesdd and zgesvd).
Minor housekeeping has also be done to the code base.
You can find the code at
http://sourceforge.net/projects/ada-lapack/
Comments, opinions, suggestions etc. are most welcome.
Cheers,
Leo
^ permalink raw reply [relevance 5%]
* Re: A thicker binding for Lapack
@ 2012-12-29 19:59 6% ` Simon Wright
0 siblings, 0 replies; 200+ results
From: Simon Wright @ 2012-12-29 19:59 UTC (permalink / raw)
jpwoodruff@gmail.com writes:
> Conclusion: transpose appears necessary.
For info, the compiler (well, GNAT) will automatically transpose when
doing assignment between arrays with different conventions. And it's
quicker (not by very much at -O2, though).
with Ada.Calendar; use Ada.Calendar;
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Numerics.Float_Random;
with Interfaces.Fortran;
with System.Generic_Array_Operations;
procedure Sauvage_Timing is
package BLAS is
-- Copied from old GNAT Interfaces.Fortran.BLAS.
-- Vector types
type Real_Vector is array (Integer range <>)
of Interfaces.Fortran.Real;
type Complex_Vector is array (Integer range <>)
of Interfaces.Fortran.Complex;
type Double_Precision_Vector is array (Integer range <>)
of Interfaces.Fortran.Double_Precision;
type Double_Complex_Vector is array (Integer range <>)
of Interfaces.Fortran.Double_Complex;
-- Matrix types
type Real_Matrix is array (Integer range <>, Integer range <>)
of Interfaces.Fortran.Real;
type Double_Precision_Matrix
is array (Integer range <>, Integer range <>)
of Interfaces.Fortran.Double_Precision;
type Complex_Matrix is array (Integer range <>, Integer range <>)
of Interfaces.Fortran.Complex;
type Double_Complex_Matrix is array (Integer range <>, Integer range <>)
of Interfaces.Fortran.Double_Complex;
end BLAS;
procedure Transpose
is new System.Generic_Array_Operations.Transpose
(Scalar => Interfaces.Fortran.Double_Precision'Base,
Matrix => BLAS.Double_Precision_Matrix);
type Double_Precision_Matrix is array (Integer range <>, Integer range <>)
of Interfaces.Fortran.Double_Precision;
pragma Convention (Fortran, Double_Precision_Matrix);
A, B : BLAS.Double_Precision_Matrix (1 .. 100, 1 .. 100);
C : Double_Precision_Matrix (1 .. 100, 1 .. 100);
pragma Volatile (B);
pragma Volatile (C);
Gen : Ada.Numerics.Float_Random.Generator;
Start, Finish : Time;
use type Interfaces.Fortran.Double_Precision;
begin
Ada.Numerics.Float_Random.Reset (Gen);
for J in A'Range (1) loop
for K in A'Range (2) loop
A (J, K) :=
Interfaces.Fortran.Double_Precision (J * K)
* Interfaces.Fortran.Double_Precision
(Ada.Numerics.Float_Random.Random (Gen));
end loop;
end loop;
Start := Clock;
for J in 1 .. 100 loop
Transpose (A, B);
end loop;
Finish := Clock;
Put_Line ("Transpose took " & Duration'Image (Finish - Start));
Start := Clock;
for J in 1 .. 100 loop
C := Double_Precision_Matrix (A);
end loop;
Finish := Clock;
Put_Line ("Assignment took" & Duration'Image (Finish - Start));
declare
Same : Boolean := True;
begin
for J in 1 .. 100 loop
for K in 1 .. 100 loop
if B (J, K) /= C (K, J) then
Same := False;
end if;
end loop;
end loop;
Put_Line ("B = ~C: " & Same'Img);
end;
end Sauvage_Timing;
^ permalink raw reply [relevance 6%]
* A thicker binding for Lapack
@ 2012-12-27 18:48 5% jpwoodruff
0 siblings, 1 reply; 200+ results
From: jpwoodruff @ 2012-12-27 18:48 UTC (permalink / raw)
There is a complete thin binding for lapack available which was
evidently started by Wasu Chaopanon in about 1996 and was recently
finished by Nasser Abbasi. There about 1000 subroutines; their
parameter signatures exactly translate the Fortran, and each procedure
is Pragma Imported.
I've been considering adding value to that binding to address two
perceived problems:
The specification involving the integer index used for matrix types is
inconsistent between the binding and Ada.Numerics.Generic_Real_Arrays.
The binding declares that type because the user's code must comply
with Fortran's integer. The Ada compiler is obliged to use that same
type. Unfortunately Generic_Real_Arrays uses the base type integer
for index, so there is no expectation that the representation would be
the same as Fortran-compiled library.
Another issue to resolve is that lapack, being Fortran, defines
column-major storage while Ada is row-major. Parameters passing
between these two conventions evidently must be transposed.
I think I have a technique for interoperating with the Ada.Numerics
types. My plan involves "wrapping" the lapack routines in a layer
that converts types and transposes matrices.
Here is a typical procedure specification as translated directly from
the fortran, with my transformation to Ada standard types.
procedure SGESV
(N : Natural;
NRHS : Natural;
A : in out Real_Arrays.Real_Matrix; -- instance of Generic_
LDA : Natural ;
IPIV : out Integer_Vector;
B : in out Real_Arrays.Real_Matrix;
LDB : Natural ;
INFO : out Integer) ;
The math requirements for this procedure are very much like the
"Solve" that was discussed in a recent thread.
-- function Solve (A : Real_Matrix; X : Real_Vector) return
-- Real_Vector;
The B parameter in sgesv resembles X in the "Why X as argument name?"
discussion. I am trying to make the lapack item as serviceable as the
gnat standard item.
My trials at maintaining parameter definitions that echo the Fortran
binding have led only to grief. The integer inputs N, NRHS, LDA, LDB
make precious little sense, considering the transposition of the
matrices that takes place inside the body of procedure sgesv.
After several drafts I'm thinking that a thick binding might look
like this:
procedure SGESV
(A : in out Real_Arrays.Real_Matrix;
IPIV : out Integer_Vector;
B : in out Real_Arrays.Real_Matrix;
INFO : out Integer) ;
Programming with Ada attributes seems to clarify the relations between
the several parameters. Now I think that the integer parameters will
be computed inside the body of the overlay procedure. Still working
on the details.
Guided by the spiral model I'll try a couple examples. Later if there
is a benefit to Ada programmers interested in numeric analysis I'll
address the scale of the massive lapack library.
Suggestions are welcome!
John
^ permalink raw reply [relevance 5%]
* Re: X : Real_Vector := Solve(A => A, X => B); -- Why X as argument name?
2012-12-24 11:50 0% ` Simon Wright
2012-12-24 12:58 0% ` Niklas Holsti
@ 2012-12-24 21:25 0% ` Gustaf Thorslund
1 sibling, 0 replies; 200+ results
From: Gustaf Thorslund @ 2012-12-24 21:25 UTC (permalink / raw)
Simon Wright <simon@pushface.org> writes:
> Niklas Holsti <niklas.holsti@tidorum.invalid> writes:
>
>> Or do you mean to ask if it was a mistake in the definition of
>> Ada.Numerics.Real_Arrays.Solve to give the second formal parameter the
>> name "X", given that "X" is a common name in client code?
>
> This is certainly a style issue. The second parameter has been 'X' ever
> since it was introduced in v4 of ai-00296 in June 2003[1]. I would
> probably have chosen 'B', but there may well be mathematical texts that
> would take the approach adopted in the ARM.
Thanks for the link! So then we are three who would have chosen 'B' over
'X'. I'm curious why 'X' was chosen. But whatever the reason was it's
already done.
> It's very common for mathematical code to adopt terse naming, in line
> with the way mathematicians seem to work, and I find it hard to think of
> sensible names for these parameters. But it ought to be possible for
> client code to be more explicit (unless, of course, the algorithm to be
> implemented was specified by one of the above-referenced mathematicians!)
When it comes to an abstract generic level it may be hard to come up
with more explicit names. A queue will have a head and tail (or some
other names). Depending on application it may be good or bad to be
first.
/Gustaf
^ permalink raw reply [relevance 0%]
* Re: X : Real_Vector := Solve(A => A, X => B); -- Why X as argument name?
2012-12-24 8:33 4% ` Niklas Holsti
2012-12-24 11:50 0% ` Simon Wright
@ 2012-12-24 20:42 0% ` Gustaf Thorslund
1 sibling, 0 replies; 200+ results
From: Gustaf Thorslund @ 2012-12-24 20:42 UTC (permalink / raw)
Niklas Holsti <niklas.holsti@tidorum.invalid> writes:
> Or you could ask, why use "X" as the name of a local variable?
Since it's a common name of an unknown in the context of linear
equations.
>
>>
>> begin
>> for I in X'Range loop
>> Put_Line(Float'Image(X(I)));
>> end loop;
>> end Why_X;
>>
>> -- Executing the program gives
>> -- $ ./why_x
>> -- 6.00000E+00
>> -- So we found the expected value of x.
>
> Do you see that as a problem? :-)
No :-) But someone reading
http://www.adaic.org/resources/add_content/standards/05rat/html/Rat-7-6.html#I1361
without a knowing what linear equations are could get a bit confused.
(in the middle of the page there is an equation "Ax = y")
>> -- Was it a misstake to use X as argument name in Solve?
>
> Do you mean, is it an error that your program uses "X" as the name of a
> local variable, when it also calls a function that has a formal
> parameter called "X"?
>
> No, it is not an error and is quite legal. The compiler knows from the
> named-association syntax ("X => ...") that "X" refers to the name of a
> formal parameter.
No, I used X intentionally to show the why it can be confusing.
> Or do you mean to ask if it was a mistake in the definition of
> Ada.Numerics.Real_Arrays.Solve to give the second formal parameter the
> name "X", given that "X" is a common name in client code?
Right!
> That is a matter of coding style and habit. (I would probably have
> chosen the name "B" for the second parameter, since "X" suggests
> "unknowns" to me, while "A" and "B" suggest "knowns".) And most coding
> style guidelines recommend against single-letter names like "X" in
> application programs, so "X" should not really be a common name.
"X" could be a common name in short examples or even a local
variable. Just like "I" and "J" in loops.
> Or do you mean to ask if it is mistake that your program uses the name
> "X" for a local variable, which the reader can confuse with the formal
> parameter "X"?
No.
> If you have no important reason to call your local variable "X", it
> would be slightly clearer to choose a different name, at least for
> readers not yet familiar with Ada.
For readers not familiar with Ada but familiar with linear equations one
might as well write:
X := Solve (A, B);
From what I see the argument name "X" doesn't really add any value
anyway.
/Gustaf
^ permalink raw reply [relevance 0%]
* Re: X : Real_Vector := Solve(A => A, X => B); -- Why X as argument name?
2012-12-23 22:28 6% X : Real_Vector := Solve(A => A, X => B); -- Why X as argument name? Gustaf Thorslund
2012-12-24 8:33 4% ` Niklas Holsti
@ 2012-12-24 20:10 0% ` jpwoodruff
1 sibling, 0 replies; 200+ results
From: jpwoodruff @ 2012-12-24 20:10 UTC (permalink / raw)
I would agree that calling the formal parameter "x" is
infelicitous. But it's been that way for a long time, so we live with
it. The important thing is that the originators made the decision and
moved on.
I'm glad the topic came up. I like to engage the people who think
this subject is interesting. I'm going to reopen the topic of Ada
bindings to Lapack, and the subject of parameter names looms in that
discussion. I'll put something up a couple days after Christmas.
Ho Ho Ho.
John
On Sunday, December 23, 2012 3:28:13 PM UTC-7, Gustaf Thorslund wrote:
> -- why_x.adb by confused Gustaf Thorslund
>
>
>
> with Ada.Numerics.Real_Arrays; use Ada.Numerics.Real_Arrays;
<...>
>
> -- x is found using
>
> -- function Solve (A : Real_Matrix; X : Real_Vector) return
>
> -- Real_Vector;
>
> X : Real_Vector := Solve(A => A, X => B); -- Why X as argument name?
>
^ permalink raw reply [relevance 0%]
* Re: X : Real_Vector := Solve(A => A, X => B); -- Why X as argument name?
2012-12-24 11:50 0% ` Simon Wright
@ 2012-12-24 12:58 0% ` Niklas Holsti
2012-12-24 21:25 0% ` Gustaf Thorslund
1 sibling, 0 replies; 200+ results
From: Niklas Holsti @ 2012-12-24 12:58 UTC (permalink / raw)
On 12-12-24 13:50 , Simon Wright wrote:
> Niklas Holsti <niklas.holsti@tidorum.invalid> writes:
>
>> Or do you mean to ask if it was a mistake in the definition of
>> Ada.Numerics.Real_Arrays.Solve to give the second formal parameter the
>> name "X", given that "X" is a common name in client code?
>
> This is certainly a style issue. The second parameter has been 'X' ever
> since it was introduced in v4 of ai-00296 in June 2003[1]. I would
> probably have chosen 'B', but there may well be mathematical texts that
> would take the approach adopted in the ARM.
There may indeed.
> It's very common for mathematical code to adopt terse naming, in line
> with the way mathematicians seem to work,
Agreed. Writing long names in chalk on a black-board (or with ink on a
white-board) is cumbersome and one quickly runs out of space.
> and I find it hard to think of
> sensible names for these parameters.
One problem is that even the subprogram name "Solve" is not according to
good practice. Firstly, an imperative verb like "Solve", should name a
procedure, not a function. For a function, a noun should be used, for
example "Solution". Secondly, "Solve" and "Solution" are really far too
general; the name should be more specific, for example
"Linear_Inverse_Image".
A more specific subprogram name could in turn suggest sensible names for
the parameters, for example "Map" for the matrix Solve.A, and "Value"
for Solve.X.
The overly general names "Solve" or "Solution" suggest parameter names
like "Problem" or "Equation", which are not so good.
> But it ought to be possible for
> client code to be more explicit (unless, of course, the algorithm to be
> implemented was specified by one of the above-referenced mathematicians!)
I have had the pleasure ;-) of implementing some computations specified
by mathematicians (well, control-theory specialist, really). The
mathematical symbols in the given equations were (as typical)
semi-fractal collections of indices and sub-indices surrounding some
base symbol on all (well, most) corners, in different alphabets (latin,
greek, etc.). The Ada identifiers logically became monsters like
"alpha_sub_i_sub_kappa".
--
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
. @ .
^ permalink raw reply [relevance 0%]
* Re: X : Real_Vector := Solve(A => A, X => B); -- Why X as argument name?
2012-12-24 8:33 4% ` Niklas Holsti
@ 2012-12-24 11:50 0% ` Simon Wright
2012-12-24 12:58 0% ` Niklas Holsti
2012-12-24 21:25 0% ` Gustaf Thorslund
2012-12-24 20:42 0% ` Gustaf Thorslund
1 sibling, 2 replies; 200+ results
From: Simon Wright @ 2012-12-24 11:50 UTC (permalink / raw)
Niklas Holsti <niklas.holsti@tidorum.invalid> writes:
> Or do you mean to ask if it was a mistake in the definition of
> Ada.Numerics.Real_Arrays.Solve to give the second formal parameter the
> name "X", given that "X" is a common name in client code?
This is certainly a style issue. The second parameter has been 'X' ever
since it was introduced in v4 of ai-00296 in June 2003[1]. I would
probably have chosen 'B', but there may well be mathematical texts that
would take the approach adopted in the ARM.
It's very common for mathematical code to adopt terse naming, in line
with the way mathematicians seem to work, and I find it hard to think of
sensible names for these parameters. But it ought to be possible for
client code to be more explicit (unless, of course, the algorithm to be
implemented was specified by one of the above-referenced mathematicians!)
[1] http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ais/ai-00296.txt?diffbase=1.3&rev=1.4
^ permalink raw reply [relevance 0%]
* Re: X : Real_Vector := Solve(A => A, X => B); -- Why X as argument name?
2012-12-23 22:28 6% X : Real_Vector := Solve(A => A, X => B); -- Why X as argument name? Gustaf Thorslund
@ 2012-12-24 8:33 4% ` Niklas Holsti
2012-12-24 11:50 0% ` Simon Wright
2012-12-24 20:42 0% ` Gustaf Thorslund
2012-12-24 20:10 0% ` jpwoodruff
1 sibling, 2 replies; 200+ results
From: Niklas Holsti @ 2012-12-24 8:33 UTC (permalink / raw)
On 12-12-24 00:28 , Gustaf Thorslund wrote:
> -- why_x.adb by confused Gustaf Thorslund
>
> with Ada.Numerics.Real_Arrays; use Ada.Numerics.Real_Arrays;
> with Ada.Text_IO; use Ada.Text_IO;
>
> procedure Why_X is
> -- Let's say we have an equation Ax = b according to the notation
> from
> -- http://en.wikipedia.org/wiki/Matrix_(mathematics)#Linear_equations
> -- where A and b are known while x is unknown.
>
> A : Real_Matrix(1..1, 1..1) := (others => (others => 2.0));
> B : Real_Vector(1..1) := (others => 12.0);
>
> -- x is found using
> -- function Solve (A : Real_Matrix; X : Real_Vector) return
> -- Real_Vector;
> X : Real_Vector := Solve(A => A, X => B); -- Why X as argument name?
Or you could ask, why use "X" as the name of a local variable?
>
> begin
> for I in X'Range loop
> Put_Line(Float'Image(X(I)));
> end loop;
> end Why_X;
>
> -- Executing the program gives
> -- $ ./why_x
> -- 6.00000E+00
> -- So we found the expected value of x.
Do you see that as a problem? :-)
> -- Was it a misstake to use X as argument name in Solve?
Do you mean, is it an error that your program uses "X" as the name of a
local variable, when it also calls a function that has a formal
parameter called "X"?
No, it is not an error and is quite legal. The compiler knows from the
named-association syntax ("X => ...") that "X" refers to the name of a
formal parameter.
Or do you mean to ask if it was a mistake in the definition of
Ada.Numerics.Real_Arrays.Solve to give the second formal parameter the
name "X", given that "X" is a common name in client code?
That is a matter of coding style and habit. (I would probably have
chosen the name "B" for the second parameter, since "X" suggests
"unknowns" to me, while "A" and "B" suggest "knowns".) And most coding
style guidelines recommend against single-letter names like "X" in
application programs, so "X" should not really be a common name.
Or do you mean to ask if it is mistake that your program uses the name
"X" for a local variable, which the reader can confuse with the formal
parameter "X"?
If you have no important reason to call your local variable "X", it
would be slightly clearer to choose a different name, at least for
readers not yet familiar with Ada.
--
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
. @ .
^ permalink raw reply [relevance 4%]
* X : Real_Vector := Solve(A => A, X => B); -- Why X as argument name?
@ 2012-12-23 22:28 6% Gustaf Thorslund
2012-12-24 8:33 4% ` Niklas Holsti
2012-12-24 20:10 0% ` jpwoodruff
0 siblings, 2 replies; 200+ results
From: Gustaf Thorslund @ 2012-12-23 22:28 UTC (permalink / raw)
-- why_x.adb by confused Gustaf Thorslund
with Ada.Numerics.Real_Arrays; use Ada.Numerics.Real_Arrays;
with Ada.Text_IO; use Ada.Text_IO;
procedure Why_X is
-- Let's say we have an equation Ax = b according to the notation
from
-- http://en.wikipedia.org/wiki/Matrix_(mathematics)#Linear_equations
-- where A and b are known while x is unknown.
A : Real_Matrix(1..1, 1..1) := (others => (others => 2.0));
B : Real_Vector(1..1) := (others => 12.0);
-- x is found using
-- function Solve (A : Real_Matrix; X : Real_Vector) return
-- Real_Vector;
X : Real_Vector := Solve(A => A, X => B); -- Why X as argument name?
begin
for I in X'Range loop
Put_Line(Float'Image(X(I)));
end loop;
end Why_X;
-- Executing the program gives
-- $ ./why_x
-- 6.00000E+00
-- So we found the expected value of x.
-- Was it a misstake to use X as argument name in Solve?
^ permalink raw reply [relevance 6%]
* Re: Press Release - Ada 2012 Language Standard Approved by ISO
2012-12-20 1:52 0% ` Randy Brukardt
@ 2012-12-21 9:01 0% ` Dmitry A. Kazakov
0 siblings, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2012-12-21 9:01 UTC (permalink / raw)
On Wed, 19 Dec 2012 19:52:33 -0600, Randy Brukardt wrote:
> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message
> news:7wrdmbre6jw9.qww9l0uzj6mg.dlg@40tude.net...
> ...
>> Take an instance of Ada.Numerics.Discrete_Random and do:
>>
>> subtype More_Fun_Number is Integer with
>> Dynamic_Predicate => Random = More_Fun_Number;
>
> A predicate (or any contract) that can get different answers on successive
> calls is *wrong*. Ada 2012 has a permission (11.4.2(27/3)) for
> implementations to reject such expressions if they can detect it. (This
> isn't required simply because we don't know of any way to characterize what
> should not be allowed -- that's a work item for future versions of Ada.)
>
> One would hope that obvious cases like this take advantage of the permission
> and are rejected outright.
People will readily misuse predicates, that is for sure. The bugs
introduced by dynamic checks are extremely difficult to track down.
> Functions in dynamic predicates (and all of the other contract aspects, as
> well) ought to be logically pure, returning the same result for the same
> parameter values.
Well, in my view there are only two purposes for type constraining. Both
are closely related:
1. Elimination of checks, that is when T'Class is constrained to specific a
S, so that dispatch became static, or when subtype Index is declared with
the range A'Range where A is an array etc. ["constant T" and "in T" fall
into this category, they disallow mutators eliminating checks that a
variable is not updated]
2. Influencing representation, e.g. setting bounds of an unconstrained
array, selecting variant of a record.
In essence 1 and 2 are about knowing something statically, during
compilation. Not necessarily the constraint itself, which may be dynamic,
yet allowing to prove something statically, e.g. that array index is always
within the bounds.
I don't see how predicates might be helpful for either 1 or 2.
subtype Even is Positive with Dynamic_Predicate => Even mod 2 = 0;
subtype Each_Second_Character is String (Even);
won't work. What I see is a yet another way to pack implementations into
declarations as Georg promptly suggested, a slippery slope...
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
^ permalink raw reply [relevance 0%]
* Re: Press Release - Ada 2012 Language Standard Approved by ISO
2012-12-19 8:33 5% ` Dmitry A. Kazakov
2012-12-19 9:00 0% ` Georg Bauhaus
2012-12-19 14:34 0% ` Bill Findlay
@ 2012-12-20 1:52 0% ` Randy Brukardt
2012-12-21 9:01 0% ` Dmitry A. Kazakov
2 siblings, 1 reply; 200+ results
From: Randy Brukardt @ 2012-12-20 1:52 UTC (permalink / raw)
"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message
news:7wrdmbre6jw9.qww9l0uzj6mg.dlg@40tude.net...
...
> Take an instance of Ada.Numerics.Discrete_Random and do:
>
> subtype More_Fun_Number is Integer with
> Dynamic_Predicate => Random = More_Fun_Number;
A predicate (or any contract) that can get different answers on successive
calls is *wrong*. Ada 2012 has a permission (11.4.2(27/3)) for
implementations to reject such expressions if they can detect it. (This
isn't required simply because we don't know of any way to characterize what
should not be allowed -- that's a work item for future versions of Ada.)
One would hope that obvious cases like this take advantage of the permission
and are rejected outright.
Functions in dynamic predicates (and all of the other contract aspects, as
well) ought to be logically pure, returning the same result for the same
parameter values.
Randy.
^ permalink raw reply [relevance 0%]
* Re: Press Release - Ada 2012 Language Standard Approved by ISO
2012-12-19 8:33 5% ` Dmitry A. Kazakov
2012-12-19 9:00 0% ` Georg Bauhaus
@ 2012-12-19 14:34 0% ` Bill Findlay
2012-12-20 1:52 0% ` Randy Brukardt
2 siblings, 0 replies; 200+ results
From: Bill Findlay @ 2012-12-19 14:34 UTC (permalink / raw)
On 19/12/2012 08:33, in article 7wrdmbre6jw9.qww9l0uzj6mg.dlg@40tude.net,
"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote:
> On Tue, 18 Dec 2012 21:12:25 +0000, Bill Findlay wrote:
>
>> On 18/12/2012 16:57, in article wcc8v8vti17.fsf@shell01.TheWorld.com,
>> "Robert A Duff" <bobduff@shell01.TheWorld.com> wrote:
>>
>>> dirk@vana.cs.kuleuven.be. (Dirk Craeynest) writes:
>>>
>>>> Ada 2012 brings significant enhancements to Ada, most notably in the
>>>> area of "contract-based programming." New features here include the
>>>> ability to specify preconditions and postconditions for subprograms,
>>>> and invariants for private (encapsulated) types.
>>>
>>> Why does everybody neglect predicates, which are more important
>>> than pre/post/invariant?
>>
>> A bit of fun with a predicate:
> [...]
>
> Take an instance of Ada.Numerics.Discrete_Random and do:
>
> subtype More_Fun_Number is Integer with
> Dynamic_Predicate => Random = More_Fun_Number;
Now that IS funnny!
--
Bill Findlay
with blueyonder.co.uk;
use surname & forename;
^ permalink raw reply [relevance 0%]
* Re: Press Release - Ada 2012 Language Standard Approved by ISO
2012-12-19 9:00 0% ` Georg Bauhaus
@ 2012-12-19 9:19 0% ` Dmitry A. Kazakov
0 siblings, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2012-12-19 9:19 UTC (permalink / raw)
On Wed, 19 Dec 2012 10:00:57 +0100, Georg Bauhaus wrote:
> On 19.12.12 09:33, Dmitry A. Kazakov wrote:
>
>> Take an instance of Ada.Numerics.Discrete_Random and do:
>>
>> subtype More_Fun_Number is Integer with
>> Dynamic_Predicate => Random = More_Fun_Number;
>
> You could use
>
> subtype More_Fun_Number is Integer with
> Dynamic_Predicate => At_Least_A_Thousand
> (Random (G), More_Fun_Number);
>
> to test whether or not your random number generator is, say,
> dodging at least 1_000 numbers that your algorithm happens
> to produce, and assign, in a predictable way.
>
> This approach doesn't seem so wrong in case one cannot know
> the result in advance, but operation of the program critically
> depends on certain properties of those unknown parts.
It is deeply wrong. A [sub]type should describe some class of entities
sharing common properties and behavior.
P.S. It is frequently said that Ada cannot not prevent you from shooting
yourself in the foot. But not with a bazooka...
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
^ permalink raw reply [relevance 0%]
* Re: Press Release - Ada 2012 Language Standard Approved by ISO
2012-12-19 8:33 5% ` Dmitry A. Kazakov
@ 2012-12-19 9:00 0% ` Georg Bauhaus
2012-12-19 9:19 0% ` Dmitry A. Kazakov
2012-12-19 14:34 0% ` Bill Findlay
2012-12-20 1:52 0% ` Randy Brukardt
2 siblings, 1 reply; 200+ results
From: Georg Bauhaus @ 2012-12-19 9:00 UTC (permalink / raw)
On 19.12.12 09:33, Dmitry A. Kazakov wrote:
> Take an instance of Ada.Numerics.Discrete_Random and do:
>
> subtype More_Fun_Number is Integer with
> Dynamic_Predicate => Random = More_Fun_Number;
>
You could use
subtype More_Fun_Number is Integer with
Dynamic_Predicate => At_Least_A_Thousand
(Random (G), More_Fun_Number);
to test whether or not your random number generator is, say,
dodging at least 1_000 numbers that your algorithm happens
to produce, and assign, in a predictable way.
This approach doesn't seem so wrong in case one cannot know
the result in advance, but operation of the program critically
depends on certain properties of those unknown parts.
^ permalink raw reply [relevance 0%]
* Re: Press Release - Ada 2012 Language Standard Approved by ISO
@ 2012-12-19 8:33 5% ` Dmitry A. Kazakov
2012-12-19 9:00 0% ` Georg Bauhaus
` (2 more replies)
0 siblings, 3 replies; 200+ results
From: Dmitry A. Kazakov @ 2012-12-19 8:33 UTC (permalink / raw)
On Tue, 18 Dec 2012 21:12:25 +0000, Bill Findlay wrote:
> On 18/12/2012 16:57, in article wcc8v8vti17.fsf@shell01.TheWorld.com,
> "Robert A Duff" <bobduff@shell01.TheWorld.com> wrote:
>
>> dirk@vana.cs.kuleuven.be. (Dirk Craeynest) writes:
>>
>>> Ada 2012 brings significant enhancements to Ada, most notably in the
>>> area of "contract-based programming." New features here include the
>>> ability to specify preconditions and postconditions for subprograms,
>>> and invariants for private (encapsulated) types.
>>
>> Why does everybody neglect predicates, which are more important
>> than pre/post/invariant?
>
> A bit of fun with a predicate:
[...]
Take an instance of Ada.Numerics.Discrete_Random and do:
subtype More_Fun_Number is Integer with
Dynamic_Predicate => Random = More_Fun_Number;
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
^ permalink raw reply [relevance 5%]
* Re: Is this a bug in Ada.Numerics?
2012-10-21 3:39 6% ` Ludovic Brenta
2012-10-21 3:54 6% ` Leo Brewin
@ 2012-10-21 8:59 6% ` Georg Bauhaus
2012-10-23 15:48 6% ` Vincent Marciante
2012-10-23 22:52 12% ` Leo Brewin
3 siblings, 0 replies; 200+ results
From: Georg Bauhaus @ 2012-10-21 8:59 UTC (permalink / raw)
On 21.10.12 05:39, Ludovic Brenta wrote:
> These rules are quite subtle and the error messages from GNAT less than
> helpful. Maybe that's why Ada has a reputation for being "difficult to
> learn".
With GNAT, try adding
-gnatwh turn on warnings for hiding declarations
(Perusing the list of compiler switches once in a while keeps being
very useful.)
^ permalink raw reply [relevance 6%]
* Re: pragma import (C, , ); -- import a constant value from C library
2012-10-27 7:40 7% ` Dmitry A. Kazakov
2012-10-27 8:15 5% ` Simon Wright
@ 2012-10-27 8:19 0% ` Simon Wright
2012-10-27 8:47 0% ` Dmitry A. Kazakov
1 sibling, 1 reply; 200+ results
From: Simon Wright @ 2012-10-27 8:19 UTC (permalink / raw)
"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
> Ada.Numerics already defines Euler's constant.
Not in ARM12! (or GNAT GPL 2012).
^ permalink raw reply [relevance 0%]
* Re: pragma import (C, , ); -- import a constant value from C library
2012-10-27 8:19 0% ` Simon Wright
@ 2012-10-27 8:47 0% ` Dmitry A. Kazakov
0 siblings, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2012-10-27 8:47 UTC (permalink / raw)
On Sat, 27 Oct 2012 09:19:30 +0100, Simon Wright wrote:
> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
>
>> Ada.Numerics already defines Euler's constant.
>
> Not in ARM12! (or GNAT GPL 2012).
You are right.
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
^ permalink raw reply [relevance 0%]
* Re: pragma import (C, , ); -- import a constant value from C library
@ 2012-10-27 7:40 7% ` Dmitry A. Kazakov
2012-10-27 8:15 5% ` Simon Wright
2012-10-27 8:19 0% ` Simon Wright
0 siblings, 2 replies; 200+ results
From: Dmitry A. Kazakov @ 2012-10-27 7:40 UTC (permalink / raw)
On Fri, 26 Oct 2012 15:45:29 -0700 (PDT), Enzo Guerra wrote:
> trying to import a constant value from C library (libgsl)
> but having no luck
>
> M_EULER : Long_Float;
> -- M_EULER, Euler's constant, \gamma
> pragma Import (C, M_EULER, "M_EULER");
>
> get error undefined reference to `M_EULER'
>
> would appreciate any help
Don't do this. Ada.Numerics already defines Euler's constant.
And in general, you can define any constant this way in Ada. The precision
is limited only by the source where you get its tabulated value. And it
will work for all real types. E.g.
gamma : constant :=
0.57721_56649_01532_86060_65120_90082_40243;
X : Long_Float := gamma;
Y : Float := gamma;
...
The compiler truncates the value when you use a narrower target like
Long_Float.
You can even perform simple calculations with such constants keeping their
huge precision. The compiler uses arbitrary-precision arithmetic for them.
E.g.
[ with Ada.Numerics; use Ada.Numerics; ]
half_pi : constant := pi / 2.0;
-- far more than enough right digits for a Long_Float
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
^ permalink raw reply [relevance 7%]
* Re: pragma import (C, , ); -- import a constant value from C library
2012-10-27 7:40 7% ` Dmitry A. Kazakov
@ 2012-10-27 8:15 5% ` Simon Wright
2012-10-27 8:19 0% ` Simon Wright
1 sibling, 0 replies; 200+ results
From: Simon Wright @ 2012-10-27 8:15 UTC (permalink / raw)
"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
> On Fri, 26 Oct 2012 15:45:29 -0700 (PDT), Enzo Guerra wrote:
>
>> trying to import a constant value from C library (libgsl)
>> but having no luck
>>
>> M_EULER : Long_Float;
>> -- M_EULER, Euler's constant, \gamma
>> pragma Import (C, M_EULER, "M_EULER");
>>
>> get error undefined reference to `M_EULER'
>>
>> would appreciate any help
>
> Don't do this. Ada.Numerics already defines Euler's constant.
>
> And in general, you can define any constant this way in Ada. The precision
> is limited only by the source where you get its tabulated value. And it
> will work for all real types. E.g.
>
> gamma : constant :=
> 0.57721_56649_01532_86060_65120_90082_40243;
>
> X : Long_Float := gamma;
> Y : Float := gamma;
> ...
>
> The compiler truncates the value when you use a narrower target like
> Long_Float.
Yes.
I worked on a project where the system engineers on the other side had
defined pi to be 3.14159 (not even 3.141592); so when we sent a Float
equal to Ada.Numerics.Pi they got a range check. We ended up agreeing
the bounds to be one mantissa bit outside the actual limit we intended.
^ permalink raw reply [relevance 5%]
* Re: Is this a bug in Ada.Numerics?
2012-10-21 2:32 12% ` Leo Brewin
@ 2012-10-21 3:39 6% ` Ludovic Brenta
2012-10-21 3:54 6% ` Leo Brewin
` (3 more replies)
0 siblings, 4 replies; 200+ results
From: Ludovic Brenta @ 2012-10-21 3:39 UTC (permalink / raw)
Leo Brewin <leo.brewin@internode.on.net> writes:
> But having digested your answer I'm still a bit confused (sorry). Here
> is the "procedure" version of the above package,
>
> with Ada.Numerics.Generic_Complex_Types;
> with Ada.Numerics.Generic_Complex_Elementary_Functions;
>
> procedure foo is
>
> type Real is digits 18;
>
> package Complex_Types is new
> Ada.Numerics.Generic_Complex_Types (Real);
>
> use foo.Complex_Types;
> subtype Complex is foo.Complex_Types.Complex;
>
> procedure bar (z : in out Complex);
>
> package Complex_Maths is new
> Ada.Numerics.Generic_Complex_Elementary_Functions (Complex_Types);
>
> procedure bar (z : in out Complex) is
> begin
> z := Complex'(Re(z),0.0);
> end bar;
>
> begin
> null;
> end foo;
>
> This does compile and yet (by my reading of your reply) the "use foo"
> and "subtype complex" lines should introduce two distinct versions of
> Complex and thus should produce a compiler error.
The difference is that, in the procedure, the subtype Foo.Complex is
declared in the immediate scope where Complex_Maths is declared, so it
hides Foo.Complex_Types.Complex, so there is no ambiguity anymore. You
get the same effect with the package if you move the declaration of
Complex_Maths to the package spec.
These rules are quite subtle and the error messages from GNAT less than
helpful. Maybe that's why Ada has a reputation for being "difficult to
learn".
--
Ludovic Brenta.
^ permalink raw reply [relevance 6%]
* Re: Is this a bug in Ada.Numerics?
2012-10-21 0:37 11% Is this a bug in Ada.Numerics? Leo Brewin
@ 2012-10-21 1:54 5% ` Yannick Duchêne (Hibou57)
2012-10-21 2:39 6% ` Leo Brewin
2012-10-21 1:55 11% ` Ludovic Brenta
1 sibling, 1 reply; 200+ results
From: Yannick Duchêne (Hibou57) @ 2012-10-21 1:54 UTC (permalink / raw)
Hi,
Just reading your snippet (not tried to compile)
Le Sun, 21 Oct 2012 02:37:36 +0200, Leo Brewin
<leo.brewin@internode.on.net> a écrit:
> In the course of my dabblings in Ada I've come across a curious
> "behaviour" that seems to me, with my limited knowledge of Ada, to be a
> bug.
>
> Here is a simple package spec
>
> with Ada.Numerics.Generic_Complex_Types;
> with Ada.Numerics.Generic_Complex_Elementary_Functions;
>
> package foo is
>
> type Real is digits 18;
>
> package Complex_Types is new
> Ada.Numerics.Generic_Complex_Types (Real);
>
> use foo.Complex_Types;
> -- subtype Complex is foo.Complex_Types.Complex;
> procedure bar (z : in out Complex);
> end foo;
When you do “use foo.Complex_Types;”, you introduce from then in the
current scope, all definitions from “foo.Complex_Types”. (by the way, you
don't need “use foo.Complex_Types;”, as “use Complex_Types;” would be
enough). This means that “foo.Complex_Types.Complex” [1] is introduced in
the scope, so there is a clash with the subtype you define right after.
May be you did not understood what exactly “use” do?
[1] See [G.1.1 Complex
Types](http://www.adaic.org/resources/add_content/standards/05rm/html/RM-G-1-1.html),
which contains the following:
type Complex is […]
> and the package body
>
> package body foo is
>
> package Complex_Maths is new
> Ada.Numerics.Generic_Complex_Elementary_Functions
> (Complex_Types);
> procedure bar (z : in out Complex) is
> begin
> z := Complex'(Re(z),0.0);
> end bar;
>
> end foo;
Not part of the case, but here, you are instantiating a generic package
which you don't use (must be an error).
--
“Syntactic sugar causes cancer of the semi-colons.” [1]
“Structured Programming supports the law of the excluded muddle.” [1]
[1]: Epigrams on Programming — Alan J. — P. Yale University
^ permalink raw reply [relevance 5%]
* Re: Is this a bug in Ada.Numerics?
2012-10-23 22:52 12% ` Leo Brewin
@ 2012-10-23 23:09 6% ` Jeffrey Carter
0 siblings, 0 replies; 200+ results
From: Jeffrey Carter @ 2012-10-23 23:09 UTC (permalink / raw)
On 10/23/2012 03:52 PM, Leo Brewin wrote:
>
> Am I missing something here?
What you experienced is a compiler error and should be reported to AdaCore. The
legality of a generic instantiation should not be affected by an unrelated
subtype declaration elsewhere in the declarative part containing the instantiation.
--
Jeff Carter
"Pray that there's intelligent life somewhere up in
space, 'cause there's bugger all down here on earth."
Monty Python's Meaning of Life
61
^ permalink raw reply [relevance 6%]
* Re: Is this a bug in Ada.Numerics?
2012-10-21 3:39 6% ` Ludovic Brenta
` (2 preceding siblings ...)
2012-10-23 15:48 6% ` Vincent Marciante
@ 2012-10-23 22:52 12% ` Leo Brewin
2012-10-23 23:09 6% ` Jeffrey Carter
3 siblings, 1 reply; 200+ results
From: Leo Brewin @ 2012-10-23 22:52 UTC (permalink / raw)
Hi Ludovic,
I thought I was getting on top of this but then I ran a small experiment that doesn't make sense (to me).
I decided to make my own generic pacakges, ada_complex_types and ada_complex_functions, as clones of
Ada.Numerics.Generic_Complex_Types and
Ada.Numerics.Generic_Complex_Elementary_Functions.
I had to add a couple of lines to the body of my packages, in particular I added these lines to
ada_complex_functions.adb
Argument_Error : Excpetion;
PI : constant := 3.14159;
and this line to ada_complex_types.adb
Argument_Error : Exception;
These changes were needed to allow compilation of the packages. Othe than the above small changes my generic packages are indetical to their Ada.Numerics counterparts.
I then used these pacakges in my previous example. I had expected no change in the errors reported by the compiler. But that is not what happens. I find that with or without the "subtype Complex ..." declaration the compiler reports no errors.
Am I missing something here?
Sorry to be a pain...
Cheers,
Leo
^ permalink raw reply [relevance 12%]
* Re: Is this a bug in Ada.Numerics?
2012-10-21 3:39 6% ` Ludovic Brenta
2012-10-21 3:54 6% ` Leo Brewin
2012-10-21 8:59 6% ` Georg Bauhaus
@ 2012-10-23 15:48 6% ` Vincent Marciante
2012-10-23 22:52 12% ` Leo Brewin
3 siblings, 0 replies; 200+ results
From: Vincent Marciante @ 2012-10-23 15:48 UTC (permalink / raw)
"Ludovic Brenta" <ludovic@ludovic-brenta.org> wrote in message
news:<87r4oscx42.fsf@ludovic-brenta.org>...
> Leo Brewin <leo.brewin@internode.on.net> writes:
> > But having digested your answer I'm still a bit confused (sorry). Here
> > is the "procedure" version of the above package,
> >
> > with Ada.Numerics.Generic_Complex_Types;
> > with Ada.Numerics.Generic_Complex_Elementary_Functions;
> >
> > procedure foo is
> >
> > type Real is digits 18;
> >
> > package Complex_Types is new
> > Ada.Numerics.Generic_Complex_Types (Real);
> >
> > use foo.Complex_Types;
> > subtype Complex is foo.Complex_Types.Complex;
> >
> > procedure bar (z : in out Complex);
> >
> > package Complex_Maths is new
> > Ada.Numerics.Generic_Complex_Elementary_Functions
> > (Complex_Types);
> >
> > procedure bar (z : in out Complex) is
> > begin
> > z := Complex'(Re(z),0.0);
> > end bar;
> >
> > begin
> > null;
> > end foo;
> >
> > This does compile and yet (by my reading of your reply) the "use foo"
> > and "subtype complex" lines should introduce two distinct versions of
> > Complex and thus should produce a compiler error.
>
> The difference is that, in the procedure, the subtype Foo.Complex is
> declared in the immediate scope where Complex_Maths is declared, so it
> hides Foo.Complex_Types.Complex, so there is no ambiguity anymore. You
> get the same effect with the package if you move the declaration of
> Complex_Maths to the package spec.
>
> These rules are quite subtle and the error messages from GNAT less than
> helpful.
This is a type of comment that AdaCore's Robert Dewar really likes to
address.
I think that there is good chance that an improvement would be made in GNAT
to address this issue if you or the original poster send a report to
AdaCore.
Vinny
> Maybe that's why Ada has a reputation for being "difficult to
> learn".
>
> --
> Ludovic Brenta.
.
^ permalink raw reply [relevance 6%]
* Re: Is this a bug in Ada.Numerics?
2012-10-21 3:39 6% ` Ludovic Brenta
@ 2012-10-21 3:54 6% ` Leo Brewin
2012-10-21 8:59 6% ` Georg Bauhaus
` (2 subsequent siblings)
3 siblings, 0 replies; 200+ results
From: Leo Brewin @ 2012-10-21 3:54 UTC (permalink / raw)
Hi Ludovic,
Thank you, that makes sense. You've been very helpful (as many on CLA can attest :).
Yes, I agree, these rules are subtle but I'm determined to get on top of them. Hence the fiddling with little examples such as the above.
Cheers,
Leo
^ permalink raw reply [relevance 6%]
* Re: Is this a bug in Ada.Numerics?
2012-10-21 1:54 5% ` Yannick Duchêne (Hibou57)
@ 2012-10-21 2:39 6% ` Leo Brewin
0 siblings, 0 replies; 200+ results
From: Leo Brewin @ 2012-10-21 2:39 UTC (permalink / raw)
On Sunday, October 21, 2012 12:54:35 PM UTC+11, Hibou57 (Yannick Duchêne) wrote:
> Not part of the case, but here, you are instantiating a generic package
>
> which you don't use (must be an error).
Hi Yannick,
Thanks for the quick reply. When I delete that unused package all of the errors I mention go away. You're right, the package is never used but its presence triggers the error I mentioned.
Cheers,
Leo
^ permalink raw reply [relevance 6%]
* Re: Is this a bug in Ada.Numerics?
2012-10-21 1:55 11% ` Ludovic Brenta
@ 2012-10-21 2:32 12% ` Leo Brewin
2012-10-21 3:39 6% ` Ludovic Brenta
0 siblings, 1 reply; 200+ results
From: Leo Brewin @ 2012-10-21 2:32 UTC (permalink / raw)
Hi Ludovic,
Thanks for the quick and detailed response. Your suggestion (3) and (4) certainly do fix the problem but I was posing the original code (in its less than ideal form) as a way to understand how the compiler sorts out these scoping/visibility issues. In my real code I would do as you suggest.
But having digested your answer I'm still a bit confused (sorry). Here is the "procedure" version of the above package,
with Ada.Numerics.Generic_Complex_Types;
with Ada.Numerics.Generic_Complex_Elementary_Functions;
procedure foo is
type Real is digits 18;
package Complex_Types is new
Ada.Numerics.Generic_Complex_Types (Real);
use foo.Complex_Types;
subtype Complex is foo.Complex_Types.Complex;
procedure bar (z : in out Complex);
package Complex_Maths is new
Ada.Numerics.Generic_Complex_Elementary_Functions (Complex_Types);
procedure bar (z : in out Complex) is
begin
z := Complex'(Re(z),0.0);
end bar;
begin
null;
end foo;
This does compile and yet (by my reading of your reply) the "use foo" and "subtype complex" lines should introduce two distinct versions of Complex and thus should produce a compiler error.
I'm sure I've got this wrong, my apologies for wasting your time...
Cheers,
Leo
^ permalink raw reply [relevance 12%]
* Re: Is this a bug in Ada.Numerics?
2012-10-21 0:37 11% Is this a bug in Ada.Numerics? Leo Brewin
2012-10-21 1:54 5% ` Yannick Duchêne (Hibou57)
@ 2012-10-21 1:55 11% ` Ludovic Brenta
2012-10-21 2:32 12% ` Leo Brewin
1 sibling, 1 reply; 200+ results
From: Ludovic Brenta @ 2012-10-21 1:55 UTC (permalink / raw)
Leo Brewin writes on comp.lang.ada:
> In the course of my dabblings in Ada I've come across a curious
> "behaviour" that seems to me, with my limited knowledge of Ada, to be
> a bug.
>
> Here is a simple package spec
>
> with Ada.Numerics.Generic_Complex_Types;
> with Ada.Numerics.Generic_Complex_Elementary_Functions;
>
> package foo is
>
> type Real is digits 18;
>
> package Complex_Types is new
> Ada.Numerics.Generic_Complex_Types (Real);
>
> use foo.Complex_Types;
> -- subtype Complex is foo.Complex_Types.Complex;
>
> procedure bar (z : in out Complex);
>
> end foo;
>
> and the package body
>
> package body foo is
>
> package Complex_Maths is new
> Ada.Numerics.Generic_Complex_Elementary_Functions (Complex_Types);
>
> procedure bar (z : in out Complex) is
> begin
> z := Complex'(Re(z),0.0);
> end bar;
>
> end foo;
>
> As it stands this package compiles under GNAT GPL 2012. But if the
> "subtype" declaration in the package spec is un-commented then the
> compile fails with the following errors
>
> 04: instantiation error at a-ngcefu.ads:24
> 04: "Complex" is not visible (more references follow)
> 04: instantiation error at a-ngcefu.ads:24
> 04: non-visible declaration at foo.ads:11
> 04: instantiation error at a-ngcefu.ads:24
> 04: non-visible declaration at a-ngcoty.ads:42, instance at foo.ads:8
> 04: instantiation error at a-ngcefu.ads:24
> 04: non-visible declaration at a-ngcoty.ads:42, instance at a-ngcefu.ads:18
>
> Is this behaviour correct? My limited understanding is that the "use
> foo.Complex_Types" should have made visible all types and operations
> on "Complex" and thus the extra "subtype" should be redundant and
> should not cause an error.
The file a-ngcefu.ads starts with:
with Ada.Numerics.Generic_Complex_Types;
generic
with package Complex_Types is new Ada.Numerics.Generic_Complex_Types (<>);
use Complex_Types;
package Ada.Numerics.Generic_Complex_Elementary_Functions is
pragma Pure;
function Sqrt (X : Complex) return Complex; -- line 24
This last line, which causes all the error messages, involves the
subtype Complex. The compiler tries to resolve this and finds two
possible solutions: Foo.Complex and Foo.Complex_Types.Complex, both of
which are directly visible. Foo.Complex is directly visible because of
your use clause at foo.ads:11 and Foo.Complex_Types.Complex is directly
visible because of the use clause at a-ngcefu.ads:19.
The compiler cannot decide which subtype is meant, so it reports an
error. I think the error is justified but the error message is cryptic.
A hint is:
> 04: non-visible declaration at a-ngcoty.ads:42, instance at foo.ads:8
> 04: non-visible declaration at a-ngcoty.ads:42, instance at a-ngcefu.ads:18
Since both subtypes are directly visible and clash, the compiler reports
both as non-visible :/
> I've tried a few variations on the above and I found that if I
> 1) Comment out the "Package Complex_Maths" declaration, OR
> 2) Create a single procedure from the above package spec/body
> then the code compiles happily with or without the "subtype"
> declaration.
You could try:
3) remove your "use Complex_Types" clause or move it to the body of your
procedure Bar.
4) remove your "subtype Foo.Complex is foo.Complex_Types.Complex"
altogether; why did you think you needed it?
> If anybody could explain this behaviour to me I would be very
> grateful.
You may think that Foo.Complex and Foo.Complex_Types.Complex are the
same thing. They are not; they are two different subtypes of the same
type; they are declared in different packages and hence have different
scopes. The fact that they have the same constraints is incidental and
irrelevant. A relevant fact is that you are allowed to add
representation clauses (or aspects) to Foo.Complex, since you declared
it, but not to Foo.Complex_Types.Complex, since it is declared by (an
instance of) a standard package.
HTH
--
Ludovic Brenta.
^ permalink raw reply [relevance 11%]
* Is this a bug in Ada.Numerics?
@ 2012-10-21 0:37 11% Leo Brewin
2012-10-21 1:54 5% ` Yannick Duchêne (Hibou57)
2012-10-21 1:55 11% ` Ludovic Brenta
0 siblings, 2 replies; 200+ results
From: Leo Brewin @ 2012-10-21 0:37 UTC (permalink / raw)
In the course of my dabblings in Ada I've come across a curious "behaviour" that seems to me, with my limited knowledge of Ada, to be a bug.
Here is a simple package spec
with Ada.Numerics.Generic_Complex_Types;
with Ada.Numerics.Generic_Complex_Elementary_Functions;
package foo is
type Real is digits 18;
package Complex_Types is new
Ada.Numerics.Generic_Complex_Types (Real);
use foo.Complex_Types;
-- subtype Complex is foo.Complex_Types.Complex;
procedure bar (z : in out Complex);
end foo;
and the package body
package body foo is
package Complex_Maths is new
Ada.Numerics.Generic_Complex_Elementary_Functions (Complex_Types);
procedure bar (z : in out Complex) is
begin
z := Complex'(Re(z),0.0);
end bar;
end foo;
As it stands this package compiles under GNAT GPL 2012. But if the "subtype" declaration in the package spec is un-commented then the compile fails with the following errors
04: instantiation error at a-ngcefu.ads:24
04: "Complex" is not visible (more references follow)
04: instantiation error at a-ngcefu.ads:24
04: non-visible declaration at foo.ads:11
04: instantiation error at a-ngcefu.ads:24
04: non-visible declaration at a-ngcoty.ads:42, instance at foo.ads:8
04: instantiation error at a-ngcefu.ads:24
04: non-visible declaration at a-ngcoty.ads:42, instance at a-ngcefu.ads:18
Is this behaviour correct? My limited understanding is that the "use foo.Complex_Types" should have made visible all types and operations on "Complex" and thus the extra "subtype" should be redundant and should not cause an error.
I've tried a few variations on the above and I found that if I
1) Comment out the "Package Complex_Maths" declaration, OR
2) Create a single procedure from the above package spec/body
then the code compiles happily with or without the "subtype" declaration.
If anybody could explain this behaviour to me I would be very grateful.
Cheers,
Leo
^ permalink raw reply [relevance 11%]
* Re: highest bit, statically determined
2012-09-30 15:39 6% ` Anatoly Chernyshev
2012-09-30 18:36 0% ` Shark8
@ 2012-10-01 8:07 0% ` Georg Bauhaus
1 sibling, 0 replies; 200+ results
From: Georg Bauhaus @ 2012-10-01 8:07 UTC (permalink / raw)
On 30.09.12 17:39, Anatoly Chernyshev wrote:
> Ouch...
> with ada.numerics.elementary_functions;
> use ada.numerics.elementary_functions;
> Highest_Bit_In_Octet:=natural(float'truncation(log(float(N),2.0)));
>
> I didn't check it for speed though. Pros that it doesn't depend on the size.
I did. And this time I had the program actually call the randomizing
Initialize I had written for the test data. .-/ Results have changed
in favor of the recursive first_1_bit_a. The test is running on a laptop,
so it likely says little about results on a microcontroller.
x an array of 12_000 octets, 10_000 iterations for each test.
First row : Count(f(x_{k}) = f(x_{k + 1})),
second row : time in seconds
68580000 2.635991000 -- f is first_1_bit
68580000 2.036651000 -- f is first_1_bit_a
68580000 27.735934000 -- f is first_1_bit_log
with inline expansion:
68580000 1.687923000
68580000 1.447859000
68580000 24.481472000
Slightly faster in both cases when translation suppresses checks,
the integer versions more than the FPT version.
^ permalink raw reply [relevance 0%]
* Re: highest bit, statically determined
2012-09-30 15:39 6% ` Anatoly Chernyshev
@ 2012-09-30 18:36 0% ` Shark8
2012-10-01 8:07 0% ` Georg Bauhaus
1 sibling, 0 replies; 200+ results
From: Shark8 @ 2012-09-30 18:36 UTC (permalink / raw)
On Sunday, September 30, 2012 9:39:41 AM UTC-6, Anatoly Chernyshev wrote:
>
> with ada.numerics.elementary_functions;
> use ada.numerics.elementary_functions;
> Highest_Bit_In_Octet:=natural(float'truncation(log(float(N),2.0)));
>
> I didn't check it for speed though. Pros that it doesn't depend on the size.
Nice!
Sometimes we get a little too caught-up in the problem-minutia we forget what the problem's really about. -- That, and some of these attributes aren't used enough to put them in the forefront of your mind when you hit a problem that can use them nicely.
^ permalink raw reply [relevance 0%]
* Re: highest bit, statically determined
@ 2012-09-30 15:39 6% ` Anatoly Chernyshev
2012-09-30 18:36 0% ` Shark8
2012-10-01 8:07 0% ` Georg Bauhaus
0 siblings, 2 replies; 200+ results
From: Anatoly Chernyshev @ 2012-09-30 15:39 UTC (permalink / raw)
Ouch...
with ada.numerics.elementary_functions;
use ada.numerics.elementary_functions;
Highest_Bit_In_Octet:=natural(float'truncation(log(float(N),2.0)));
I didn't check it for speed though. Pros that it doesn't depend on the size.
^ permalink raw reply [relevance 6%]
* Re: problem with Real_Matrix*Real_Matrix
2012-09-17 13:37 6% problem with Real_Matrix*Real_Matrix reinkor
@ 2012-09-17 17:01 0% ` Niklas Holsti
0 siblings, 0 replies; 200+ results
From: Niklas Holsti @ 2012-09-17 17:01 UTC (permalink / raw)
On 12-09-17 16:37 , reinkor wrote:
> Dear All,
>
> I am confused about my result from the multiplication r*M where
> r is Real_Vector and M is Real_Matrix. Enclosed is my test program
> including comments. Could someone look at it and maybe help me out
> of my bubble?
>
>
> I use gcc-ada-4.7-2.1.1.x86_64 under OpenSuse 12.2
I get the expected result:
** r*M :
3010.0 4020.0
on my Mac, with GNAT 4.5.0 20100221 (experimental) [trunk revision 156937].
I suspect your Ada installation is broken, but I don't have any advice
on how to fix it, sorry.
--
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
. @ .
>
> reinert
>
>
> with Text_IO;
> use Text_IO;
> with ada.numerics.Generic_Real_Arrays;
>
> with Ada.Strings.Fixed;
> use Ada.Strings,Ada.Strings.Fixed;
>
>
> procedure test3 is
>
> type Real is new Float;
>
> package Real_Io is new Text_IO.Float_Io (Real);
> use Real_Io;
>
> package Int_Io is new Text_IO.Integer_Io (Integer);
> use Int_Io;
>
> package GRA is new Ada.Numerics.Generic_Real_Arrays(Real);
> use GRA;
>
> procedure Put (X : Real_Vector) is
> begin
> for I in X'Range (1) loop
> Put (X (I),6,1,0);
> end loop;
> end Put;
>
> M : Real_Matrix := ((1.0, 2.0),
> (3.0, 4.0));
>
> r : Real_Vector := (10.0,1000.0);
>
> begin
>
> Put("** r*M : ");New_Line;
> Put(r*M);
>
> -- Extect: r*M = (10*1 + 1000*3, 10*2 + 1000*4) = (3010,4020)
> -- i.e. should r*M consists of the inner product between r and
> -- the columns of M ? But my program gives:
> --
> -- ** r*M :
> -- 40.0 6000.0
> --
>
> end test3;
>
>
^ permalink raw reply [relevance 0%]
* problem with Real_Matrix*Real_Matrix
@ 2012-09-17 13:37 6% reinkor
2012-09-17 17:01 0% ` Niklas Holsti
0 siblings, 1 reply; 200+ results
From: reinkor @ 2012-09-17 13:37 UTC (permalink / raw)
Dear All,
I am confused about my result from the multiplication r*M where
r is Real_Vector and M is Real_Matrix. Enclosed is my test program
including comments. Could someone look at it and maybe help me out
of my bubble?
I use gcc-ada-4.7-2.1.1.x86_64 under OpenSuse 12.2
reinert
with Text_IO;
use Text_IO;
with ada.numerics.Generic_Real_Arrays;
with Ada.Strings.Fixed;
use Ada.Strings,Ada.Strings.Fixed;
procedure test3 is
type Real is new Float;
package Real_Io is new Text_IO.Float_Io (Real);
use Real_Io;
package Int_Io is new Text_IO.Integer_Io (Integer);
use Int_Io;
package GRA is new Ada.Numerics.Generic_Real_Arrays(Real);
use GRA;
procedure Put (X : Real_Vector) is
begin
for I in X'Range (1) loop
Put (X (I),6,1,0);
end loop;
end Put;
M : Real_Matrix := ((1.0, 2.0),
(3.0, 4.0));
r : Real_Vector := (10.0,1000.0);
begin
Put("** r*M : ");New_Line;
Put(r*M);
-- Extect: r*M = (10*1 + 1000*3, 10*2 + 1000*4) = (3010,4020)
-- i.e. should r*M consists of the inner product between r and
-- the columns of M ? But my program gives:
--
-- ** r*M :
-- 40.0 6000.0
--
end test3;
^ permalink raw reply [relevance 6%]
* Re: Question: re Image Files.
@ 2012-08-31 22:09 5% ` Shark8
0 siblings, 0 replies; 200+ results
From: Shark8 @ 2012-08-31 22:09 UTC (permalink / raw)
Here's one for you then. It builds a shuffled array over the given type, which can be used to index into something like a deck of cards or somesuch.
Generic
Type Element is (<>);
Low : Natural:= Element'Pos(Element'First);
High : Natural:= Element'Pos(Element'Last);
Package Random is
SubType Element_Range is Integer Range Low..High;
Function Incrementor Return Element;
Type Element_Array is Array(Element_Range) of Element;
Values : Element_Array;
Procedure Print;
End Random;
--------------------------
With
Ada.Text_IO,
Ada.Numerics.Discrete_Random;
Use
Ada.Text_IO;
Package Body Random is
Count : Element := Element'First;
Function To_Integer( Input : in Element ) Return Element_Range is
begin
Return Low;
end;
Function Incrementor Return Element is
begin
Return Result : Element:= Count do
Null;
Count:= Element'Succ( Result );
Exception
When Constraint_Error => Count:= Element'First;
End Return;
end Incrementor;
Procedure Swap( Index_1, Index_2 : In Integer ) is
Temp : Constant Element:= Values( Integer(Index_1) );
begin
Values( Integer(Index_1) ):= Values( Integer(Index_2) );
Values( Integer(Index_2) ):= Temp;
end Swap;
Procedure Print is
begin
Put_Line( "Length: " & Values'Length'Img );
Put( "(" );
For Index in Values'First..Integer'Pred(Values'Last) loop
Put( Values(Index)'Img & ',' );
end loop;
Put( Values(Values'Last)'Img );
Put_Line( ")" );
end Print;
Begin
null;
Shuffle:
Declare
Package Random_Element is New
Ada.Numerics.Discrete_Random( Element_Range );
Number : Random_Element.Generator;
Use Random_Element;
Function Random( Gen : Generator ) Return Element_Range
Renames Random_Element.Random;
Begin
Reset( Number );
Values:= Element_Array'( Others => Incrementor );
For Index in Element_Array'Range loop
Swap( Index, Random(Number) );
end loop;
End Shuffle;
End Random;
^ permalink raw reply [relevance 5%]
* Re: ada lapack
2012-08-18 16:33 5% ` Ada novice
2012-08-18 17:32 7% ` Simon Wright
@ 2012-08-18 20:45 0% ` Niklas Holsti
1 sibling, 0 replies; 200+ results
From: Niklas Holsti @ 2012-08-18 20:45 UTC (permalink / raw)
On 12-08-18 19:33 , Ada novice wrote:
> Yes Nasser I do remember that post of yours well. That's a pity.
>
> I hope that someone can come up with a solution to this problem. It's
> unblievable that one has to "reinvent the wheel". Of course in the
> same program, one would want to be able to mix the lapack codes with
> those of Ada numerics seamlessly.
The problem is that Ada_Lapack is a conversion from Fortran to
Fortran-style Ada, and not a true native Ada implementation.
I wonder why Ada_Lapack needs convention-Fortran matrices, when it does
not use any Fortran code. Perhaps the reason is the frequent use in
Ada_Lapack of "for X'Address use Y", where X is an array. Yuck. But
writing a native Ada clone of LAPACK could be a lot of work, and might
need some deep understanding of how the Fortran LAPACK works.
--
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
. @ .
^ permalink raw reply [relevance 0%]
* Re: ada lapack
2012-08-18 16:33 5% ` Ada novice
@ 2012-08-18 17:32 7% ` Simon Wright
2012-08-18 20:45 0% ` Niklas Holsti
1 sibling, 0 replies; 200+ results
From: Simon Wright @ 2012-08-18 17:32 UTC (permalink / raw)
Ada novice <shai.lesh@gmx.com> writes:
> I hope that someone can come up with a solution to this problem. It's
> unblievable that one has to "reinvent the wheel". Of course in the
> same program, one would want to be able to mix the lapack codes with
> those of Ada numerics seamlessly.
The types from Ada.Numerics are convention Ada by default, while the
types in Ada_Lapack are convention Fortran.
It would be nice to be able to say something like
with Ada.Numerics.Generic_Complex_Arrays;
generic
with package Complex_Arrays
is new Ada.Numerics.Generic_Complex_Arrays (<>);
package Conventions is
type Complex_Matrix
is new Complex_Arrays.Complex_Matrix with Convention => Fortran;
which would give you the operations you want, but unfortunately
gcc -c -gnat12 conventions.ads
conventions.ads:9:46: representation item appears too late
conventions.ads:9:46: primitive operations already defined for "Complex_Matrix"
gnatmake: "conventions.ads" compilation error
> It's definitely an issue that Ada programmers need to look into if we
> would like to attract people to use Ada.
Who are these "Ada programmers"? Looks to me as though it's you, Leo and
Nasser!
^ permalink raw reply [relevance 7%]
* Re: ada lapack
2012-08-18 15:22 5% ` Nasser M. Abbasi
@ 2012-08-18 16:33 5% ` Ada novice
2012-08-18 17:32 7% ` Simon Wright
2012-08-18 20:45 0% ` Niklas Holsti
0 siblings, 2 replies; 200+ results
From: Ada novice @ 2012-08-18 16:33 UTC (permalink / raw)
Yes Nasser I do remember that post of yours well. That's a pity.
I hope that someone can come up with a solution to this problem. It's unblievable that one has to "reinvent the wheel". Of course in the same program, one would want to be able to mix the lapack codes with those of Ada numerics seamlessly.
It's definitely an issue that Ada programmers need to look into if we would like to attract people to use Ada.
YC
^ permalink raw reply [relevance 5%]
* Re: ada lapack
2012-08-18 13:48 5% ` Ada novice
@ 2012-08-18 15:22 5% ` Nasser M. Abbasi
2012-08-18 16:33 5% ` Ada novice
0 siblings, 1 reply; 200+ results
From: Nasser M. Abbasi @ 2012-08-18 15:22 UTC (permalink / raw)
On 8/18/2012 8:48 AM, Ada novice wrote:
> Thanks. This is rather unfortunate to see that one cannot use the many operators
>and functions in Ada.Numerics.Generic_Complex_Arrays in example file example01.adb
>automatically. Adding two matrices is simple but other functions are not so easy to implement.
>
> YC
>
I already found this "issue" and mentioned it before here in this newsgroup
when I was working on the Ada Lapack package by Wasu Chaopanon.
see
http://coding.derkeiler.com/Archive/Ada/comp.lang.ada/2012-07/msg00290.html
"The Ada lapack binding defines its own Matrix types. However, it
does not define operators (multiply, add, etc.. ) to work on these
types similar to Ada's Real Vectors and Matrices in the
Ada.Numerics.Real_Arrays package"
Yes. Each time a new type is made, one in Ada, you must define
a new set of operators on this type.
--Nasser
^ permalink raw reply [relevance 5%]
* Re: ada lapack
2012-08-18 13:13 5% ` Niklas Holsti
@ 2012-08-18 13:48 5% ` Ada novice
2012-08-18 15:22 5% ` Nasser M. Abbasi
0 siblings, 1 reply; 200+ results
From: Ada novice @ 2012-08-18 13:48 UTC (permalink / raw)
Thanks. This is rather unfortunate to see that one cannot use the many operators and functions in Ada.Numerics.Generic_Complex_Arrays in example file example01.adb automatically. Adding two matrices is simple but other functions are not so easy to implement.
YC
^ permalink raw reply [relevance 5%]
* Re: ada lapack
@ 2012-08-18 13:13 5% ` Niklas Holsti
2012-08-18 13:48 5% ` Ada novice
0 siblings, 1 reply; 200+ results
From: Niklas Holsti @ 2012-08-18 13:13 UTC (permalink / raw)
On 12-08-18 14:57 , Ada novice wrote:
> If in an example file given say example01.adb one needs to add 2
> matrices. We have the given "matrix" and we can make a copy
> "matrix_copy". Writing
>
> sum_two_matrices := matrix + matrix_copy;
>
> gives an compilation error
>
> ---there is no applicable operator "+" for type "Complex_Matrix" at
> ada_lapack.ads:69, instance at line 24---
>
> The Complex_Matrix type defined in G.3.2 complex vectors and matrices
> of the ARM can do addition + operations. The Complex_Matrix as
> defined in ada_lapack.ads:69 seems different.
They are indeed different types. The standard package
Ada.Numerics.Generic_Complex_Arrays provides the "+" operator (and
several other operators) but ada_lapack.ads does not.
If you want a "+" for Ada_Lapack.Complex_Matrix, you must define one
yourself, either in ada_lapack.ads/adb (best option) or in your own
code. You code the "+" function just like any other Ada function, except
that its name is "+":
function "+" (Left, Right : Complex_Matrix) return Complex_Matrix
is
begin
...
end "+";
--
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
. @ .
^ permalink raw reply [relevance 5%]
* Re: Ada.Locales pseudo-string types
@ 2012-08-08 14:05 5% ` Georg Bauhaus
0 siblings, 0 replies; 200+ results
From: Georg Bauhaus @ 2012-08-08 14:05 UTC (permalink / raw)
On 08.08.12 13:35, Niklas Holsti wrote:
> In my professional area (worst-case execution-time analysis),
> compiler-generated implicit loops are often a problem, especially in Ada
> programs. A restriction identifier to forbid such loops (at least when
> the number of iterations is dynamic) could be useful here, and would let
> programmers choose between a restrictive or a permissive coding style.
Controlling the translation of array operations seems to be
a tricky business, with, apparently, many of the properties of
an Ada implementation being considered in addition to the
array itself. Maybe the pragmas would have to be rather
detailed?
In the following example, I get a plain loop for array assignment
only for a very specific array length, with an 8 bits component type,
even at very low optimization settings. The compiler seems to have
a rich repertoire from which to choose what to emit for assignments.
The assignment of array X to array Y has been isolated in
procedure Assign.
package Types is
pragma Pure (Types);
Does_Not_Unroll : constant := 129;
-- Values below 129 will generate unrolled array assignment,
-- four components at a time;
-- Values 129 and above yield rep; movsq on Intel;
-- Values 8193 and above will call _memcpy.
type Idx is range 1 .. Does_Not_Unroll;
type Vlu is mod 256;
type Ary is array (Idx) of Vlu;
end Types;
with Ada.Numerics.Discrete_Random;
with Types;
package Bitmaker is new
Ada.Numerics.Discrete_Random (Types.Vlu);
with Bitmaker;
with Types; use Types;
procedure Hidden (Result : out Vlu) is
G : Bitmaker.Generator;
X, Y : Ary;
procedure Assign is
begin
Y := X;
end Assign;
begin
for K in X'Range loop
X (K) := Bitmaker.Random (G);
end loop;
Assign;
declare
Pick : constant Vlu := X (X'First);
Position : constant Idx :=
Idx'First + Idx'Min (Idx'Last - 1, Vlu'Pos (Pick));
begin
Result := Y (Position);
end;
end Hidden;
^ permalink raw reply [relevance 5%]
* Re: Does Ada need elemental functions to make it suitable for scientific work?
2012-07-10 8:39 5% ` Nasser M. Abbasi
2012-07-12 0:22 0% ` robin.vowels
@ 2012-07-20 1:51 0% ` Randy Brukardt
1 sibling, 0 replies; 200+ results
From: Randy Brukardt @ 2012-07-20 1:51 UTC (permalink / raw)
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 3093 bytes --]
"Nasser M. Abbasi" <nma@12000.org> wrote in message
news:jtgpos$20g$2@speranza.aioe.org...
> On 7/10/2012 3:02 AM, gautier.de.montmollin@gmail.com wrote:
>> Le mardi 10 juillet 2012 07:22:58 UTC+2, Ada novice a �crit :
>>
>>> Believe me, for someone who do numerical computations on a daily basis,
>>> an operation
>>like V**2 is a NECESSITY. It's a pity that Ada does not offer such a
>>facility.
>>I do not blame those who stick to Matlab (or Fortran?) for doing numerical
>>computations.
>>
>> Wait... There are *such* facilities and several built-in operations
>> *like* that:
>> http://www.ada-auth.org/standards/12rm/html/RM-G-3-1.html
>>
>> Apparently it is not enough. But it is possible to make a proposal for
>> the next standard (and short term for the next GNAT version).
>>
>
> That is a start. But not enough by any means. All functions should be
> vectorized. Even user defined ones.
That would be a complete change in philosophy for Ada. The expectation is
that everything that can reasonably be done in libraries will be done that
way. Note that Ada didn't add advanced containers directly in the syntax.
It might be reasonable to propose to add additional operators to the Ada
language to make this more possible. We did look at that for Ada 2005 and
decided not to do it, mainly because most of the interesting operators are
not unary or binary. (Think integration and differentiation.)
> In Ada, I can't even take the sin of a vector
Of course you can, with a trivial loop.
for E of Vect loop
E := Sin(E);
end loop;
And this has the distinct advantage of making it clear to other readers what
it is that you are doing.
> ----------------------
> with Ada.Numerics.Elementary_Functions;
> use Ada.Numerics.Elementary_Functions;
>
> procedure foo3 is
> type array_t is array(1..5) OF float;
> D : constant array_t :=(0.1,0.2,0.3,0.4,0.5);
> V : array_t;
> begin
> -- V := sin(D); -- ERROR
>
> for I in D'Range loop -- must use a LOOP
> V(I) := sin(D(I));
> end loop;
> end foo3;
> --------------------
>
> I can ofcourse overload sin, hide the loop inside my own sine
> and then do
>
> V:= myPackage.sin(D);
>
> All of this is possible in Ada.
Right. And this is what you are supposed to do.
Note that in any case the Sin you are calling is not specially known to the
compiler, so there is no benefit to having the compiler vectorize it: it
will end up writing the loop anyway. (And hardware implementations of Sin
generally do not meet Ada's checking and accuracy requirements, so it's hard
to use them even if the compiler could recognize them.)
> It is just a little (alot?) more effort compared to what is out there.
Writing functions is what you do in Ada. And Ada is always about
readability, including for those who aren't familar with your code.
Things like Matlab have a very different purpose than Ada and of course are
going to be easier to write. Ease of writing is not now and never will be a
goal for Ada!
Randy.
^ permalink raw reply [relevance 0%]
* Re: Efficient Sequential Access to Arrays
@ 2012-07-15 21:44 5% ` Georg Bauhaus
0 siblings, 0 replies; 200+ results
From: Georg Bauhaus @ 2012-07-15 21:44 UTC (permalink / raw)
On 15.07.12 22:03, Keean Schupke wrote:
> On Sunday, 15 July 2012 20:48:35 UTC+1, Dmitry A. Kazakov wrote:
>> On Sun, 15 Jul 2012 11:40:08 -0700 (PDT), Keean Schupke wrote:
>>
>> > However in order to achieve this performance I needed to rework the arrays
>> > as the use of Indexes was too slow.
>>
>> You have to measure it in order to know. Write two variants and compare
>> their performance.
>
> Have done, the difference is about 10k simulations per second.
>
>>
>> > An example of this is lets say we are
>> > accessing element 5 from array A "A(5)" this requires a multiplication to
>> > access (base_address + index * record_size).
>>
>> It does not, because 5 is constant.
>
> Obviously the index is not actually a constant but the result of selecting a random element in the list. The multiplication is necessary for finding this first element, but the operations on relative elements (+/-1, +/-2 etc) can use addition with a pointer, not so with an index.
There is address arithmetic in System.*. For the simple case of
constant distances, something like the following might have some
hints. Or it might if redone after thinking. procedure Grab has
the multiplication for offsets of components of a record type
object in an array.
The point is that one may express offsets by referring
to type attributes that follow from representation clauses
and then convert between addresses and pointers.
with Ada.Numerics.Float_Random; use Ada.Numerics.Float_Random;
with System.Address_To_Access_Conversions, System.Storage_Elements;
procedure Iter_Arrays (Size : Natural) is
Storage_Elements : constant := 1;
type Index is mod 2**32;
type Data is digits 6;
for Data'Size use 32;
G : Generator;
type Things is record
One: Data := Data (Random (G));
Two: Data := Data (Random (G));
end record;
for Things use record
One at 0 * Storage_Elements range 0 .. Data'Size - 1;
Two at 4 * Storage_Elements range 0 .. Data'Size - 1;
end record;
pragma Assert (Things'Size = 64);
type List is array (Index range <>) of Things;
for List'Alignment use 4 * Storage_Elements;
for List'Component_Size use 64;
-- using array indexing
procedure Bumble (A : in out List; Step : Index) is
begin
for K in A'First + Step .. A'Last - Step loop
declare
Diff_Backward : constant Data := A (K).One - A (K - Step).Two;
Diff_Forward : constant Data := A (K).Two - A (K + Step).One;
begin
if (abs Diff_Backward) < (abs Diff_Forward) then
A (K).One := A (K - Step).One;
else
A (K).Two := A (K + Step).Two;
end if;
end;
end loop;
end Bumble;
-- using relative addresses
package Indirection is new System.Address_To_Access_Conversions
(Object => Data);
subtype Data_Pointer is Indirection.Object_Pointer;
procedure Grab (A : in out List; Step : Index) is
-- [A] = [one][two][one][two]...[one][two]
use System.Storage_Elements, Indirection;
Offset_Backward : constant Storage_Offset :=
Storage_Offset (0 + Step * 8 + 4);
Offset_Forward : constant Storage_Offset :=
Storage_Offset (0 - Step * 8 + 0);
begin
for K in A'First + Step .. A'Last - Step loop
declare
Back : constant Data_Pointer :=
To_Pointer (A (K).One'Address + Offset_Backward);
Ahead : constant Data_Pointer :=
To_Pointer (A (K).Two'Address + Offset_Backward);
Diff_Backward : constant Data := A (K).One - Back.all;
Diff_Forward : constant Data := A (K).One - Ahead.all;
begin
if (abs Diff_Backward) < (abs Diff_Forward) then
A (K).One := A (K - Step).One;
else
A (K).Two := A (K + Step).Two;
end if;
end;
end loop;
end Grab;
Test_Data : List (0 .. Index(Size));
begin
Bumble (Test_Data, 2);
Grab (Test_Data, 3);
end Iter_Arrays;
^ permalink raw reply [relevance 5%]
* Re: Pre-Ada95 books still worth reading
@ 2012-07-15 20:09 4% ` wrp
0 siblings, 0 replies; 200+ results
From: wrp @ 2012-07-15 20:09 UTC (permalink / raw)
On Jul 15, 6:33 am, Ada novice <shai.l...@gmx.com> wrote:
> Books I have seen:
>
> 1. Haberman. Ada for Experienced Programmers
> Compares Ada and Pascal side by side.
Yeah. The title should be _A Comparison of Ada and Pascal_. If that is
what you want, a review I read said that Haberman did a good job. The
question is whether the contents are now too dated.
> 2. Ford. Scientific Ada
> Discusses a few algorithms here and there but otherwise not much interesting.
I sometimes see questions from researchers trying to choose Fortran
vs. Ada for numerical work. This seems to be the only book-length
evaluation of Ada in that respect. I wonder how it compares to the
relevant parts of _Ada as a Second Language_ or _Programming in Ada
2005_.
Contents:
1. The Rationale for Ada
2. Ada as General Scientific Language
3. Ada and Fortran
4. Pascal to Ada Conversion
5. Ada and Other Scientific Languages: A Critique
6. Ada: Style and Recommendations
7. Ada: Numerics
8. Ada Packages
9. Ada: Error Mechanisms, Exceptions and Generics
10. Guidelines for the Design of Large Modular Scientific Libraries in
Ada
> Haven't seen this one:
> Pyle. Developing Safety Systems: A Guide Using Ada
Here are some snips from a review. Sounds like it might still have
some useful tidbits.
...The construction of software for critical systems is addressed in
three sections covering requirements analysis, design principles, and
quality assurance...
...The section on design deals with general principles of software
design, static structure using Ada packages, algorithm design in Ada,
and controlling devices in Ada...
...the author has a clear understanding of correctness, formality, and
rigor, concepts that sometimes suffer from poor explanation...
^ permalink raw reply [relevance 4%]
* Re: How to initialize a matrix of one column only?
2012-07-09 9:35 5% ` Simon Wright
@ 2012-07-12 4:13 0% ` Jerry
0 siblings, 0 replies; 200+ results
From: Jerry @ 2012-07-12 4:13 UTC (permalink / raw)
On Jul 9, 2:35 am, Simon Wright <si...@pushface.org> wrote:
> > I wish these bindings would be rewritten to use Annex G.3 Real_Vector
> > and Real_Matrix (etc. for complex) so that a single set of types can
> > be used in a program that uses the G.3 stuff anyway.
>
> The problem with that is that the BLAS is a Fortran library, so expects
> Fortran conventions for matrices. The Ada_BLAS bindings are thin, so
> don't do the transposition required .
>
> The old GNAT Ada.Numerics.Generic_{Real,Complex}_Arrays did the
> transposition explicitly.
>
> There was a discussion about this (and performance aspects) on this
> group:http://groups.google.com/group/comp.lang.ada/browse_frm/thread/5395b8...
OS X ships with both Fortran and C versions of BLAS and LAPACK, so I
would suppose the C version is common. Wouldn't using the C versions
solve this problem? As I recall, both Ada and C are row major.
Jerry
^ permalink raw reply [relevance 0%]
* Re: Lapack Ada binding matrices/vectors issue, how to best to resolve?
2012-07-12 0:38 7% Lapack Ada binding matrices/vectors issue, how to best to resolve? Nasser M. Abbasi
@ 2012-07-12 0:45 0% ` Nasser M. Abbasi
0 siblings, 0 replies; 200+ results
From: Nasser M. Abbasi @ 2012-07-12 0:45 UTC (permalink / raw)
On 7/11/2012 7:38 PM, Nasser M. Abbasi wrote:
>
> ---------------------------
> with Interfaces.Fortran; use Interfaces.Fortran;
> with Ada.Numerics.Real_Arrays; use Ada.Numerics.Real_Arrays;
> with labase; use labase; -- LAPACK binding
>
> procedure foo3 is
>
> A1 : constant Fortran_Real_Matrix(1..2,1..2):=
> 12.0*((12.0, 6.0),(-12.0, 6.0)); -- ERROR
>
> A2 : constant Real_Matrix(1..2,1..2) :=
> 12.0*((12.0, 6.0),(-12.0, 6.0)); -- OK
> begin
> null;
> end foo3;
> --------------------
>
opps that should be foo3.adb in the command below (I copied the file content
to new file and named it foo3, but pasted the older command on the window which
was foo2.adb)
>> gnatmake -gnat2012 -I/lapada/ada foo2.adb -largs -lblas
> gcc -c -gnat2012 -I/lapada/ada foo2.adb
> foo2.adb:24:20: expected type "Fortran_Real_Matrix" defined at labase.ads:94
> foo2.adb:24:20: found type "Interfaces.Fortran.Complex"
> gnatmake: "foo2.adb" compilation error
>>
>
here is the command again:
>gnatmake -gnat2012 -I/lapada/ada foo3.adb -largs -lblas
gcc -c -gnat2012 -I/lapada/ada foo3.adb
foo3.adb:10:13: expected type "Fortran_Real_Matrix" defined at labase.ads:94
foo3.adb:10:13: found type "Complex_Star_16" defined at labase.ads:52
gnatmake: "foo3.adb" compilation error
>
(I just did not want someone to get confused if they saw this).
--Nasser
^ permalink raw reply [relevance 0%]
* Lapack Ada binding matrices/vectors issue, how to best to resolve?
@ 2012-07-12 0:38 7% Nasser M. Abbasi
2012-07-12 0:45 0% ` Nasser M. Abbasi
0 siblings, 1 reply; 200+ results
From: Nasser M. Abbasi @ 2012-07-12 0:38 UTC (permalink / raw)
The Ada lapack binding defines its own Matrix types. However, it
does not define operators (multiply, add, etc.. ) to work on these
types similar to Ada's Real Vectors and Matrices in the
Ada.Numerics.Real_Arrays package
http://www.ada-auth.org/standards/12rm/html/RM-G-3-1.html
What this means, is that one can't even multiply a number by the
matrix if the Matrix is Fortran_Real_Matrix like one can with
Real_Matrix. Here is a simple example
---------------------------
with Interfaces.Fortran; use Interfaces.Fortran;
with Ada.Numerics.Real_Arrays; use Ada.Numerics.Real_Arrays;
with labase; use labase; -- LAPACK binding
procedure foo3 is
A1 : constant Fortran_Real_Matrix(1..2,1..2):=
12.0*((12.0, 6.0),(-12.0, 6.0)); -- ERROR
A2 : constant Real_Matrix(1..2,1..2) :=
12.0*((12.0, 6.0),(-12.0, 6.0)); -- OK
begin
null;
end foo3;
--------------------
>gnatmake -gnat2012 -I/lapada/ada foo2.adb -largs -lblas
gcc -c -gnat2012 -I/lapada/ada foo2.adb
foo2.adb:24:20: expected type "Fortran_Real_Matrix" defined at labase.ads:94
foo2.adb:24:20: found type "Interfaces.Fortran.Complex"
gnatmake: "foo2.adb" compilation error
>
I tried to do conversion of the Fortran_Real_Matrix to
Real_Matrix but the compiler does not like it as it is
aggregate.
So, this means this binding as it stands is too limited to
use as is.
What would be a good way to fix this whole issue? Make a
pacakge similar to Numerics.Generic_Real_Arrays for
the Fortran_Real_Matrix so that all the operators '*','+', etc..
are available now for this Matrix type?
The Ada lapack package with's :
with Ada.Numerics.Generic_Complex_Types;
with Interfaces.Fortran; use Interfaces.Fortran;
Then it defines many types, such as
----------------------
type Fortran_Integer_Matrix is array (Fortran_Integer range <>,
Fortran_Integer range <>)
of Fortran_Integer;
pragma Convention (Fortran, Fortran_Integer_Matrix);
etc..
----------------------
But it does NOT define operators to work on these types like
the Ada package Ada.Numerics.Real_Arrays does:
-------------------------------
function "*" (Left : Real'Base; Right : Real_Matrix)
return Real_Matrix;
---------------------------
I was thinking of just copying all these functions as the above to the
Lapack package and edit things and change all the Real_Matrix to
Fortran_Real_Matrix etc.. but this seems like not the right way
to do this.
The main Lapack package is lapada/ada/labase.ads in
the tar file
ftp://ftp.cs.kuleuven.be/pub/Ada-Belgium/mirrors/gnu-ada/OLD/contrib/lapack-ada/
Any suggestion how to resolve this from experts will be great as I am
a newbie in Ada.
--Nasser
^ permalink raw reply [relevance 7%]
* Re: Does Ada need elemental functions to make it suitable for scientific work?
2012-07-10 8:39 5% ` Nasser M. Abbasi
@ 2012-07-12 0:22 0% ` robin.vowels
2012-07-20 1:51 0% ` Randy Brukardt
1 sibling, 0 replies; 200+ results
From: robin.vowels @ 2012-07-12 0:22 UTC (permalink / raw)
Cc: nma
On Tuesday, 10 July 2012 18:39:58 UTC+10, Nasser M. Abbasi wrote:
> On 7/10/2012 3:02 AM, gautier.de...@gmail.com wrote:
> > Le mardi 10 juillet 2012 07:22:58 UTC+2, Ada novice a écrit :
> >
> >> Believe me, for someone who do numerical computations on a daily basis, an operation
> >like V**2 is a NECESSITY. It&#39;s a pity that Ada does not offer such a facility.
> >I do not blame those who stick to Matlab (or Fortran?) for doing numerical computations.
> >
> > Wait... There are *such* facilities and several built-in operations *like* that:
> > http://www.ada-auth.org/standards/12rm/html/RM-G-3-1.html
> >
> > Apparently it is not enough. But it is possible to make a proposal for
> > the next standard (and short term for the next GNAT version).
> >
>
> That is a start. But not enough by any means. All functions should be
> vectorized. Even user defined ones.
>
> In Ada, I can't even take the sin of a vector
But you can in PL/I.
> ----------------------
> with Ada.Numerics.Elementary_Functions;
> use Ada.Numerics.Elementary_Functions;
>
> procedure foo3 is
> type array_t is array(1..5) OF float;
> D : constant array_t :=(0.1,0.2,0.3,0.4,0.5);
> V : array_t;
>
> begin
> -- V := sin(D); -- ERROR
>
> for I in D'Range loop -- must use a LOOP
> V(I) := sin(D(I));
> end loop;
>
> end foo3;
> --------------------
>
> I can ofcourse overload sin, hide the loop inside my own sine
> and then do
>
> V:= myPackage.sin(D);
>
> All of this is possible in Ada. It is just a little (alot?)
> more effort compared to what is out there.
>
> octave/Matlab:
> --------------------------
> D=[0.1,0.2,0.3,0.4,0.5];
> sin(D)
>
> ans =
> 0.0998 0.1987 0.2955 0.3894 0.4794
> ---------------------------
and PL/I.
> > The snag with that *specific* operation, v**2 meaning "v(i)**2 for each i",
> >is that it is counter-intuitive from a linear algebra point of view. You
> >would rather expect v**2 = v*v. Now another snag is should "*" be the
> >dot or the cross product ?...
> >
> > These kind of things are thought-out carefully before landing into an Ada standard...
> >
>
> But these issue have been solved long time time. (like maybe
> 30 years ago? and are well defined for all cases:
More like 45 years ago,
for PL/I has had that facility since 1966.
For vectors, matrices (in fact multi-dimensional arrays),
and for cross-sections of arrays.
^ permalink raw reply [relevance 0%]
* Re: Free AMD Core Math Library (BLAS/LAPACK) + Ada
2012-07-11 9:47 5% ` Ken Thomas
@ 2012-07-11 19:30 0% ` Simon Wright
0 siblings, 0 replies; 200+ results
From: Simon Wright @ 2012-07-11 19:30 UTC (permalink / raw)
Ken Thomas <kst@ecs.soton.ac.uk> writes:
> Perhaps we should remember the motivation of the BLAS/LAPACK. A
> standard specification that is implemented by hardware companies such
> as Intel, AMD using all the wizardry to obtain high performance. A
> related question is given the Ada .Numerics package
> Generic_Real_Arrays how do we modify the build to link in the high
> performance tools?
Well, with GNAT GPL 2012/GCC 4.7 you can't, because Generic_Real_Arrays
has been rewritten in pure Ada (using Jacobi, which I gather is not
known to be fast) in order not to use BLAS because of a feeling that
some BLAS's might use an unacceptable numeric approximation. Personally
I think this was daft.
^ permalink raw reply [relevance 0%]
* Re: Free AMD Core Math Library (BLAS/LAPACK) + Ada
@ 2012-07-11 9:47 5% ` Ken Thomas
2012-07-11 19:30 0% ` Simon Wright
0 siblings, 1 reply; 200+ results
From: Ken Thomas @ 2012-07-11 9:47 UTC (permalink / raw)
On Wednesday, July 11, 2012 8:49:03 AM UTC+1, Simon Wright wrote:
> Ada novice <shai.lesh@gmx.com> writes:
>
> > 2. I will install the acml-4-4-0-gfortran-32bit.tgz from ACML. Hope
> > this works! Nevertheless I saw some lapack files already on my
> > Linux. So should I just disregard these?
>
> The reason you were pursuing ACML was that you might have been able to
> get it to work with Ada *on Windows*. On Linux, you can use the
> already-packaged LAPACK/BLAS libraries (as Nasser has said, you'll need
> to load them using the package manager; I'd expect loading LAPACK would
> automagically load BLAS).
Perhaps we should remember the motivation of the BLAS/LAPACK. A standard specification that is implemented by hardware companies such as Intel, AMD using all the wizardry to obtain high performance. A related question is given the Ada .Numerics package Generic_Real_Arrays how do we modify the build to link in the high performance tools?
^ permalink raw reply [relevance 5%]
* Re: Does Ada need elemental functions to make it suitable for scientific work?
[not found] ` <637de084-0e71-4077-a1c5-fc4200cad3cf@googlegroups.com>
2012-07-10 8:39 5% ` Nasser M. Abbasi
@ 2012-07-10 12:46 5% ` Brian Drummond
1 sibling, 0 replies; 200+ results
From: Brian Drummond @ 2012-07-10 12:46 UTC (permalink / raw)
On Tue, 10 Jul 2012 01:02:13 -0700, gautier.de.montmollin wrote:
> Le mardi 10 juillet 2012 07:22:58 UTC+2, Ada novice a écrit :
>
>> Believe me, for someone who do numerical computations on a daily basis,
>> an operation like V**2 is a NECESSITY. It's a pity that Ada does
>> not offer such a facility. I do not blame those who stick to Matlab (or
>> Fortran?) for doing numerical computations.
>
> Wait... There are *such* facilities and several built-in operations
> *like* that:
> http://www.ada-auth.org/standards/12rm/html/RM-G-3-1.html
>
> Apparently it is not enough. But it is possible to make a proposal for
> the next standard (and short term for the next GNAT version).
Furthermore, they are not really "built-in", so there is no need to go
back to the standards authority if you feel they are lacking. The source
for Ada.Numerics.Generic_Real_Array is right there, and contains no magic.
Adding "**" to suit your own purposes should be no more complicated than
the implementation of "+" in Ada.Numerics.Generic_Real_Array.
So, how does that work?
Ada.Numerics.Generic_Real_Array is found (on my machine) at
/usr/lib/gcc/i586-suse-linux/4.6/adainclude/a-ngrear.ads (specification)
and /usr/lib/gcc/i586-suse-linux/4.6/adainclude/a-ngrear.adb (body)
The specification is
function "+" (Right : Real_Vector) return Real_Vector;
...
pragma Inline_Always ("+");
The body - you might expect a loop , performing addition on each element.
Well, not quite...
----------------------------------------------------------------------
with System.Generic_Array_Operations; use System.Generic_Array_Operations;
...
-- Instantiating the following subprograms directly would lead to
-- name clashes, so use a local package.
package Instantiations is
...
function "+" is new
Vector_Vector_Elementwise_Operation
(Left_Scalar => Real'Base,
Right_Scalar => Real'Base,
Result_Scalar => Real'Base,
Left_Vector => Real_Vector,
Right_Vector => Real_Vector,
Result_Vector => Real_Vector,
Operation => "+");
...
end Instantiations;
function "+" (Left, Right : Real_Vector) return Real_Vector
renames Instantiations."+";
----------------------------------------------------------------------
So it uses a generic function from System.Generic_Array_Operations to
loop over the vector, applying the Operation argument to each element.
And this generic function is available for you to use in the same manner.
(There are similar ones for unary operations like sin(), and others for
2D matrix operations, etc)
So you can create a package along the same lines, and add **, sin, etc to
it. Once you have the package in place, adding more matrix operations of
your own is trivial.
What does this generic function look like?
Excerpt from System.Generic_Array_Operations - on this system, at
/usr/lib/gcc/i586-suse-linux/4.6/adainclude/s-gearop.ads(specification)
--------------------------------
generic
type Left_Scalar is private;
type Right_Scalar is private;
type Result_Scalar is private;
type Left_Vector is array (Integer range <>) of Left_Scalar;
type Right_Vector is array (Integer range <>) of Right_Scalar;
type Result_Vector is array (Integer range <>) of Result_Scalar;
with function Operation
(Left : Left_Scalar;
Right : Right_Scalar) return Result_Scalar;
function Vector_Vector_Elementwise_Operation
(Left : Left_Vector;
Right : Right_Vector) return Result_Vector;
--------------------------------
which should be enough information to let you use it...
If you are curious about its implementation, look at
/usr/lib/gcc/i586-suse-linux/4.6/adainclude/s-gearop.adb (body)
--------------------------------
-----------------------------------------
-- Vector_Vector_Elementwise_Operation --
-----------------------------------------
function Vector_Vector_Elementwise_Operation
(Left : Left_Vector;
Right : Right_Vector) return Result_Vector
is
R : Result_Vector (Left'Range);
begin
if Left'Length /= Right'Length then
raise Constraint_Error with
"vectors are of different length in elementwise operation";
end if;
for J in R'Range loop
R (J) := Operation (Left (J), Right (J - R'First + Right'First));
end loop;
return R;
end Vector_Vector_Elementwise_Operation;
--------------------------------
which is of course the expected loop, plus a sanity check.
- Brian
^ permalink raw reply [relevance 5%]
* Re: Does Ada need elemental functions to make it suitable for scientific work?
[not found] ` <637de084-0e71-4077-a1c5-fc4200cad3cf@googlegroups.com>
@ 2012-07-10 8:39 5% ` Nasser M. Abbasi
2012-07-12 0:22 0% ` robin.vowels
2012-07-20 1:51 0% ` Randy Brukardt
2012-07-10 12:46 5% ` Brian Drummond
1 sibling, 2 replies; 200+ results
From: Nasser M. Abbasi @ 2012-07-10 8:39 UTC (permalink / raw)
On 7/10/2012 3:02 AM, gautier.de.montmollin@gmail.com wrote:
> Le mardi 10 juillet 2012 07:22:58 UTC+2, Ada novice a �crit :
>
>> Believe me, for someone who do numerical computations on a daily basis, an operation
>like V**2 is a NECESSITY. It's a pity that Ada does not offer such a facility.
>I do not blame those who stick to Matlab (or Fortran?) for doing numerical computations.
>
> Wait... There are *such* facilities and several built-in operations *like* that:
> http://www.ada-auth.org/standards/12rm/html/RM-G-3-1.html
>
> Apparently it is not enough. But it is possible to make a proposal for
> the next standard (and short term for the next GNAT version).
>
That is a start. But not enough by any means. All functions should be
vectorized. Even user defined ones.
In Ada, I can't even take the sin of a vector
----------------------
with Ada.Numerics.Elementary_Functions;
use Ada.Numerics.Elementary_Functions;
procedure foo3 is
type array_t is array(1..5) OF float;
D : constant array_t :=(0.1,0.2,0.3,0.4,0.5);
V : array_t;
begin
-- V := sin(D); -- ERROR
for I in D'Range loop -- must use a LOOP
V(I) := sin(D(I));
end loop;
end foo3;
--------------------
I can ofcourse overload sin, hide the loop inside my own sine
and then do
V:= myPackage.sin(D);
All of this is possible in Ada. It is just a little (alot?)
more effort compared to what is out there.
octave/Matlab:
--------------------------
D=[0.1,0.2,0.3,0.4,0.5];
sin(D)
ans =
0.0998 0.1987 0.2955 0.3894 0.4794
---------------------------
> The snag with that *specific* operation, v**2 meaning "v(i)**2 for each i",
>is that it is counter-intuitive from a linear algebra point of view. You
>would rather expect v**2 = v*v. Now another snag is should "*" be the
>dot or the cross product ?...
>
> These kind of things are thought-out carefully before landing into an Ada standard...
>
But these issue have been solved long time time. (like maybe
30 years ago? and are well defined for all cases:
http://www.mathworks.com/help/techdoc/ref/arithmeticoperators.html
There are element-wise operators, and operators that work
on the whole vector or matrix.
In octave/Matlab world, V.^2 means element-wise. (notice
the ".")
-------------------------
octave:3> V=[1 2 3 4];
octave:4> v.^2
ans =
1 4 9 16
--------------------------
Otherwise, it becomes standard matrix operation.
A^2 means A*A
------------------------
octave:17> A=[1 2;3 4]
A =
1 2
3 4
octave:18> A^2
ans =
7 10
15 22
octave:19> A*A
ans =
7 10
15 22
---------------------
To do dot product, it has its own operator, called dot() !
----------------------
octave:5> dot(V,V)
ans = 30
-------------------------
To do cross product, it has its own operator, called cross() !
-----------------------
octave:9> D=[1 2 3]; V=[3 4 5]; cross(D,V)
ans =
-2 4 -2
-------------------
btw, in Mathematica, it is the other way around. V*V does
element by element multiplication, and V.V does matrix product.
It has also Dot[] and Cross[] and all functions are vectorized,
and all user defined functions can be vectorized by simply
giving them the attribute Listable.
--Nasser
^ permalink raw reply [relevance 5%]
* Re: How to initialize a matrix of one column only?
@ 2012-07-09 9:35 5% ` Simon Wright
2012-07-12 4:13 0% ` Jerry
0 siblings, 1 reply; 200+ results
From: Simon Wright @ 2012-07-09 9:35 UTC (permalink / raw)
Jerry <lanceboyle@qwest.net> writes:
> On Jul 7, 5:08 pm, "Nasser M. Abbasi" <n...@12000.org> wrote:
>
>> where the labase package simply introduces a type for
>> Fortran_Real_Matrix as follows
>>
>> ----------------------------
>> type Fortran_Real_Matrix is array (Fortran_Integer range <>,
>> Fortran_Integer range <>)
>> of Real;
>> pragma Convention (Fortran, Fortran_Real_Matrix);
>
> I wish these bindings would be rewritten to use Annex G.3 Real_Vector
> and Real_Matrix (etc. for complex) so that a single set of types can
> be used in a program that uses the G.3 stuff anyway.
The problem with that is that the BLAS is a Fortran library, so expects
Fortran conventions for matrices. The Ada_BLAS bindings are thin, so
don't do the transposition required .
The old GNAT Ada.Numerics.Generic_{Real,Complex}_Arrays did the
transposition explicitly.
There was a discussion about this (and performance aspects) on this
group:
http://groups.google.com/group/comp.lang.ada/browse_frm/thread/5395b8f41548bf11/37bcbb133b8d5a62?lnk=gst&q=sauvage#37bcbb133b8d5a62
^ permalink raw reply [relevance 5%]
* Re: GNAT and Dimension Checking
@ 2012-07-06 10:47 2% ` AdaMagica
0 siblings, 0 replies; 200+ results
From: AdaMagica @ 2012-07-06 10:47 UTC (permalink / raw)
I would like to invite all of you interested in dimensional algebra to a lively discussion about the findings in packages provided by GNAT.
I played around a bit and here are mine.
GNAT Dimension_System Findings
==================================
Very clever use of the new aspect facilty.
Should be considered for standardisation in next Ada generation.
Currently very poorly documented.
There are a few minor problems and some (in my honest opinion) more severe
ones in output.
The following is based on the (Gaussian) CGS system.
type CGS_Gauss is new Long_Long_Float
with Dimension_System => ((Centimeter, "cm"),
(Gram , 'g'),
(Second , 's'));
package CGS_Gauss_IO is new System.Dim.Float_IO (CGS_Gauss);
use CGS_Gauss_IO;
subtype Length is CGS_Gauss
with Dimension => ("cm",
Centimeter => 1,
others => 0);
subtype Mass is CGS_Gauss
with Dimension => ("g",
Gram => 1,
others => 0);
subtype Time is CGS_Gauss
with Dimension => ("s",
Second => 1,
others => 0);
cm: constant Length := 1.0;
g : constant Mass := 1.0;
s : constant Time := 1.0;
0. The syntax of aspects Dimension_System and Dimension is not documented.
--------------------------------------------------------------------------
It might seem obvious, but documentation is needed nevertheless.
In Dimension_System, up to 7 base dimensions may be defined (more lead to
a compilation error, less are tolerated).
1. How to define objects for dimensions without name?
-----------------------------------------------------
Imagine you have some charge, but not defined a subtype Charge.
Q: CGS_Gauss := 40.0 * cm**(3/2)*g**(1/2)/s; -- ???
This fails with
dimensions mismatch in object declaration
object type is dimensionless
object expression has dimensions (3/2, 1/2, -1)
It's no problem to define the subtype
subtype Charge is CGS_Gauss
with Dimension => ("esu",
Centimeter => 3/2,
Gram => 1/2,
Second => -1);
and then write
Q: Charge := 40.0 * cm**(3/2)*g**(1/2)/s;
but it is often the case that some intermediate value has to be stored
with an unnamed dimension. Very inconvenient if you have to locally
define a subtype for this.
** Dimension should be taken from the initial expression! **
2. Obviously GNAT can handle fractional dimensions.
---------------------------------------------------
This is very comfortable.
Q: Charge := 40.0 * cm**(3/2)*g**(1/2)/s;
R: Length := 10.0 * cm;
Put (Q**2/R**2 , Aft => 2, Exp => 0); New_Line;
Put (Q**2/R**2 , Aft => 2, Exp => 0, Symbols => "dyn"); New_Line;
Put ((Q/R)**(5/7), Aft => 2, Exp => 0); New_Line;
16.00 cm.g.s**(-2)
2.69 cm**(5/14).g**(5/14).s**(-5/7)
However, I cannot find where
function (Left: Dim_Type; Right: Rational) return Dim_Type;
is defined, let alone the type Rational.
The definition of Rational is flawed.
Don't write
(8.0*cm)**(1/3+2/3)
this has the value 1. This, howver, is correct:
(8.0*cm)**((1+2)/(5-2)) = 8.0*cm
(Admittedly, who would write such nonsense? Dimension checking is only done
for static expressions.)
Ahem - be careful:
8.0**(1/3) = 1
8.0**(1/3)*cm = 2.0*cm
(8.0*cm)**(1/3) = 2.0*cm**(1/3)
You need a dimensioned value to give the correct result:
One: constant CGS_Gauss := 1.0; -- dimension 1, i.e. "dimensionless"
8.0**(1/3)*One = 2.0
(In SI, results never have fractional dimensions, but intermediate values
may. So this is important also for SI.)
3. System.Dim.Float_IO is only output.
--------------------------------------
Values are correctly output with their dimension, very nice.
However, the name Float_IO is a lie, there is no dimensional input.
Input would be hard to achieve with the output syntax as produced now because
how to determine whether a dimension to read follows a number or not since
there is a separating space. We would need a multiplication sign instead.
Put (Q**2/R**2, Aft => 2, Exp => 0);
results in
16.00 cm.g.s**(-2) <=== How to read this back in?
Also the exponent in an output like 1.0 m**2.s could be taken as the
floating point number 2.0 when trying to read it in again (in input, missing
fore or aft is allowed).
Compare with
16.00*cm.g.s**(-2) <=== This is dimensioned.
So checking the input for syntactic and semantic correctness is not easy.
Adding a symbol for the output is not checked! You can write any nonsense.
Put (Q**2/R**2, Aft => 2, Exp => 0, Symbols => "dyn"); New_Line;
Put (Q**2/R**2, Aft => 2, Exp => 0, Symbols => "m/s"); New_Line;
16.00dyn <=== space missing (dyn undefined)!
16.00m/s <=== nonsense!
R: Length := 10.0 * cm;
Put (R, Aft => 2, Exp => 0); New_Line;
Put (R, Aft => 2, Exp => 0, Symbols => "km"); New_Line;
10.00 cm <=== OK
10.00km <=== Surprise, surprise!
This behaviour is apt to lead to confusion and program bugs!
4. Mathematics is included!
===========================
package Math is new Ada.Numerics.Generic_Elementary_Functions (CGS_Gauss);
use Math;
Any function requires dimensionless parameters and returns a dimensionless
result, except Sqrt, which correcly calculates the root of the dimension.
However:
function Sin (X, Cycle : Float_Type'Base) return Float_Type'Base;
(Cos, Tan, Cot) should allow dimensioned parameters when both have the same
dimension.
function Arcsin (X, Cycle : Float_Type'Base) return Float_Type'Base;
(Arccos) should request X dimensionless and the return value should be
dimensioned like Cycle.
function Arctan (Y: Float_Type'Base;
X: Float_Type'Base := 1.0[;
Cycle : Float_Type'Base]) return Float_Type'Base;
(Arccot) should allow X and Y with the same dimension [and be dimensioned
like Cycle].
------------------------------------------
Any thoughts, other nice features or awkward shortcomings?
^ permalink raw reply [relevance 2%]
* Re: What would you like in Ada202X?
2012-07-04 17:55 5% ` Simon Wright
@ 2012-07-04 18:35 0% ` Nasser M. Abbasi
0 siblings, 0 replies; 200+ results
From: Nasser M. Abbasi @ 2012-07-04 18:35 UTC (permalink / raw)
On 7/4/2012 12:55 PM, Simon Wright wrote:
> "Nasser M. Abbasi" <nma@12000.org> writes:
>
>> Need to install blas and lapack yourself first. Use Atlas blas.
>
> Since Ada.Numerics.Generic[_Complex]_Arrays already depend on BLAS and
> LAPACK I'd have thought they'd come with GNAT (if not already on the
> platform, as they are with Mac OS X).
>
If I just do gnatmake on the file that uses laplack binding, (the
example test program, which makes direct calls to lapack), it
will complain, during the link process, about missing symbols in blas.
so the linker does not see them.
So that is why I had to point it to linux installed blas/lapack
area to get the link to work as I showed in the command above.
But if I call solve() in Ada to solve Ax=b (which I assume
ends up making a call to lapack SGESV(), then I do not need
to anything other just type gnatmake. I guess it knows then
where these libraries are. Not sure how. It could be using then
the gnat-own supplied copy of blas, may be located in other area
known to gnatmake. I have not looked into it more.
--Nasser
^ permalink raw reply [relevance 0%]
* Re: What would you like in Ada202X?
@ 2012-07-04 17:55 5% ` Simon Wright
2012-07-04 18:35 0% ` Nasser M. Abbasi
0 siblings, 1 reply; 200+ results
From: Simon Wright @ 2012-07-04 17:55 UTC (permalink / raw)
"Nasser M. Abbasi" <nma@12000.org> writes:
> Need to install blas and lapack yourself first. Use Atlas blas.
Since Ada.Numerics.Generic[_Complex]_Arrays already depend on BLAS and
LAPACK I'd have thought they'd come with GNAT (if not already on the
platform, as they are with Mac OS X).
^ permalink raw reply [relevance 5%]
* Reason for elements of 'ada.numerics.generic_real_arrays' real_vector and real_matrix types not being aliased ?
@ 2012-06-30 2:40 6% rodakay
0 siblings, 0 replies; 200+ results
From: rodakay @ 2012-06-30 2:40 UTC (permalink / raw)
Hi folks,
I guess the subject speaks for itself. Would anyone know the
reason ?
regards,
Rod.
^ permalink raw reply [relevance 6%]
* Re: how to print an array range?
2012-06-26 13:47 6% how to print an array range? Nasser M. Abbasi
@ 2012-06-28 6:59 0% ` Shark8
1 sibling, 0 replies; 200+ results
From: Shark8 @ 2012-06-28 6:59 UTC (permalink / raw)
Cc: nma
On Tuesday, June 26, 2012 8:47:01 AM UTC-5, Nasser M. Abbasi wrote:
> simple question from newbie. How do I print array range?
> I tried using image' attribute, but can't get the syntax to
> work right.
>
> ----------------------------
> with Ada.Text_Io; use Ada.Text_Io;
> with Ada.Float_Text_Io; use Ada.Float_Text_Io;
> with Ada.integer_Text_Io; use Ada.integer_Text_Io;
> with Ada.Numerics.Real_Arrays; use Ada.Numerics.Real_Arrays;
>
> procedure foo1 is
> A : constant Real_Matrix :=
> (( 1.0, 2.0, 3.0),
> ( 4.0, 5.0, 6.0),
> ( 7.0, 8.0, 9.0));
> begin
>
> put(A'range(1));
>
> end foo1;
> ----------------------
>
> I expected to see "1..3". How do you use image' on this
> or other way to display the range?
>
> thanks,
> --Nasser
Ok, let's say you have Array_Type which is defined as Array (Integer Range <>) of Integer. We can achieve this by the following function:
Procedure Put_Range( A : In Array_Type ) is
Use Text_IO, Integer_IO;
begin
Put( A'First );
Put( ".." );
Put( A'Last );
end Put_Range;
For a mulch-dimensional array you would do something similar either a) calling the given function as an iteration through the minor-index, or b) expanding the above with the 'Range(Index_Number) attribute. {If I remember the attribute name correctly.}
^ permalink raw reply [relevance 0%]
* Re: Why this error, value not in range of subtype of "Standard.Integer"?
2012-06-26 15:49 6% Why this error, value not in range of subtype of "Standard.Integer"? Nasser M. Abbasi
2012-06-26 17:20 0% ` Adam Beneschan
2012-06-26 18:00 4% ` Niklas Holsti
@ 2012-06-26 21:39 0% ` Robert A Duff
2 siblings, 0 replies; 200+ results
From: Robert A Duff @ 2012-06-26 21:39 UTC (permalink / raw)
"Nasser M. Abbasi" <nma@12000.org> writes:
> If I write this, I get an error as show: (notice the B
> matrix declaration, that is where the problem is)
>
> -------------- this does not work ------
> with Ada.Numerics.Real_Arrays; use Ada.Numerics.Real_Arrays;
>
> procedure foo2 is
> A : constant Real_Matrix :=
> (( 1.0, 2.0, 3.0),
> ( 4.0, 5.0, 6.0),
> ( 7.0, 8.0, 9.0));
> B : Real_Matrix(1 .. 3,1 .. 3); -- this is the problem
Others answered your question, but: You might find it convenient
to declare a subtype:
subtype My_Real_Matrix is Real_Matrix(1..3, 1..3);
A: constant My_Real_Matrix := ((1.0, ....
B: My_Real_Matrix;
Also look into the "for ... of" syntax of Ada 2012.
- Bob
^ permalink raw reply [relevance 0%]
* Re: Why this error, value not in range of subtype of "Standard.Integer"?
2012-06-26 15:49 6% Why this error, value not in range of subtype of "Standard.Integer"? Nasser M. Abbasi
@ 2012-06-26 17:20 0% ` Adam Beneschan
2012-06-26 18:00 4% ` Niklas Holsti
2012-06-26 21:39 0% ` Robert A Duff
2 siblings, 0 replies; 200+ results
From: Adam Beneschan @ 2012-06-26 17:20 UTC (permalink / raw)
On Tuesday, June 26, 2012 8:49:18 AM UTC-7, Nasser M. Abbasi wrote:
> experts;
>
> If I write this, I get an error as show: (notice the B
> matrix declaration, that is where the problem is)
>
> -------------- this does not work ------
> with Ada.Numerics.Real_Arrays; use Ada.Numerics.Real_Arrays;
>
> procedure foo2 is
> A : constant Real_Matrix :=
> (( 1.0, 2.0, 3.0),
> ( 4.0, 5.0, 6.0),
> ( 7.0, 8.0, 9.0));
> B : Real_Matrix(1 .. 3,1 .. 3); -- this is the problem
> begin
>
> FOR I in A'range(1) LOOP
> FOR J in A'range(2) LOOP
> B(I,J) := 1.0;
> END LOOP;
> END LOOP;
>
> end foo2;
> -------------------------------
>
> >gnatmake foo2.adb
> gcc-4.6 -c foo2.adb
> foo2.adb:13:17: warning: value not in range of subtype of "Standard.Integer" defined at line 8
> foo2.adb:13:17: warning: "Constraint_Error" will be raised at run time
> foo2.adb:13:19: warning: value not in range of subtype of "Standard.Integer" defined at line 8
> foo2.adb:13:19: warning: "Constraint_Error" will be raised at run time
> gnatbind -x foo2.ali
> gnatlink foo2.ali
>
> But if I change the declaration of B from
> B : Real_Matrix(1 .. 3,1 .. 3);
> to
> B : Real_Matrix(A'RANGE(1), A'RANGE(2));
>
> then Ada is happy now.
>
> Isn't A'RANGE(1) the same as 1 .. 3 and A'RANGE(2) the same as 1 .. 3?
> or is this one of those typing issues?
A'Range(1) is the same as A'First(1) .. A'Last(1), which is in this case -2147483648 .. -2147483646, not 1 .. 3. I've said more about this in my response on another thread.
-- Adam
^ permalink raw reply [relevance 0%]
* Re: Why this error, value not in range of subtype of "Standard.Integer"?
2012-06-26 15:49 6% Why this error, value not in range of subtype of "Standard.Integer"? Nasser M. Abbasi
2012-06-26 17:20 0% ` Adam Beneschan
@ 2012-06-26 18:00 4% ` Niklas Holsti
2012-06-26 21:39 0% ` Robert A Duff
2 siblings, 0 replies; 200+ results
From: Niklas Holsti @ 2012-06-26 18:00 UTC (permalink / raw)
On 12-06-26 18:49 , Nasser M. Abbasi wrote:
> experts;
>
> If I write this, I get an error as show: (notice the B
> matrix declaration, that is where the problem is)
No, the problem is in the declaration of the A matrix. Or really in the
difference in their declarations.
> -------------- this does not work ------
> with Ada.Numerics.Real_Arrays; use Ada.Numerics.Real_Arrays;
>
> procedure foo2 is
> A : constant Real_Matrix :=
> (( 1.0, 2.0, 3.0),
> ( 4.0, 5.0, 6.0),
> ( 7.0, 8.0, 9.0));
The Real_Matrix type is defined in Ada.Numerics.Real_Arrays with Integer
as the index type:
type Real_Matrix is array (Integer range <>, Integer range <>)
of Real'Base;
This means that the matrix A, which is constrained by its initial value,
has the lower index bounds Integer'First, which in the case of 32-bit
integers is -2147483648, and the upper index bound is Integer'First + 2,
which is -2147483646. Far out of the range of the indices of B, 1..3.
Change the declaration of A to specify the index ranges:
A : constant Real_Matrix (1 .. 3, 1 .. 3) :=
> But if I change the declaration of B from
> B : Real_Matrix(1 .. 3,1 .. 3);
> to
> B : Real_Matrix(A'RANGE(1), A'RANGE(2));
>
> then Ada is happy now.
Yep. Now B also has the index range Integer'First .. Integer'First + 2.
> Isn't A'RANGE(1) the same as 1 .. 3 and A'RANGE(2) the same as 1 .. 3?
That would be the case, if Real_Matrix were defined with Positive as the
index range. But not with Integer.
--
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
. @ .
^ permalink raw reply [relevance 4%]
* Why this error, value not in range of subtype of "Standard.Integer"?
@ 2012-06-26 15:49 6% Nasser M. Abbasi
2012-06-26 17:20 0% ` Adam Beneschan
` (2 more replies)
0 siblings, 3 replies; 200+ results
From: Nasser M. Abbasi @ 2012-06-26 15:49 UTC (permalink / raw)
experts;
If I write this, I get an error as show: (notice the B
matrix declaration, that is where the problem is)
-------------- this does not work ------
with Ada.Numerics.Real_Arrays; use Ada.Numerics.Real_Arrays;
procedure foo2 is
A : constant Real_Matrix :=
(( 1.0, 2.0, 3.0),
( 4.0, 5.0, 6.0),
( 7.0, 8.0, 9.0));
B : Real_Matrix(1 .. 3,1 .. 3); -- this is the problem
begin
FOR I in A'range(1) LOOP
FOR J in A'range(2) LOOP
B(I,J) := 1.0;
END LOOP;
END LOOP;
end foo2;
-------------------------------
>gnatmake foo2.adb
gcc-4.6 -c foo2.adb
foo2.adb:13:17: warning: value not in range of subtype of "Standard.Integer" defined at line 8
foo2.adb:13:17: warning: "Constraint_Error" will be raised at run time
foo2.adb:13:19: warning: value not in range of subtype of "Standard.Integer" defined at line 8
foo2.adb:13:19: warning: "Constraint_Error" will be raised at run time
gnatbind -x foo2.ali
gnatlink foo2.ali
But if I change the declaration of B from
B : Real_Matrix(1 .. 3,1 .. 3);
to
B : Real_Matrix(A'RANGE(1), A'RANGE(2));
then Ada is happy now.
Isn't A'RANGE(1) the same as 1 .. 3 and A'RANGE(2) the same as 1 .. 3?
or is this one of those typing issues?
---------------------------------------------
with Ada.Numerics.Real_Arrays; use Ada.Numerics.Real_Arrays;
procedure foo1 is
A : constant Real_Matrix :=
(( 1.0, 2.0, 3.0),
( 4.0, 5.0, 6.0),
( 7.0, 8.0, 9.0));
B : Real_Matrix(A'RANGE(1), A'RANGE(2));
begin
FOR I in A'range(1) LOOP
FOR J in A'range(2) LOOP
B(I,J) := 1.0;
END LOOP;
END LOOP;
end foo1;
------------------------------
(one thing I like about Ada, is that once the program compiles clean,
then it runs fine !)
thanks
--Nasser
^ permalink raw reply [relevance 6%]
* Re: how to print an array range?
2012-06-26 14:08 6% ` Nasser M. Abbasi
@ 2012-06-26 14:24 6% ` Nasser M. Abbasi
0 siblings, 0 replies; 200+ results
From: Nasser M. Abbasi @ 2012-06-26 14:24 UTC (permalink / raw)
On 6/26/2012 9:08 AM, Nasser M. Abbasi wrote:
...
> put(A'First(1)); new_line;
> put(A'Last(1));
>
> end foo1;
> ----------------------------
>
>> gnatmake foo1.adb
> gcc-4.6 -c foo1.adb
> gnatbind -x foo1.ali
> gnatlink foo1.ali
>> ./foo1
> -2147483648
> -2147483646
I think I know what these numbers are. Look like Integer'first.
But I wanted to see the range of
the first dimension of the Matrix A below. (1..3, 1..3)
----------------------------------
with Ada.Text_Io; use Ada.Text_Io;
with Ada.Float_Text_Io; use Ada.Float_Text_Io;
with Ada.integer_Text_Io; use Ada.integer_Text_Io;
with Ada.Numerics.Real_Arrays; use Ada.Numerics.Real_Arrays;
procedure foo1 is
A : constant Real_Matrix :=
(( 1.0, 2.0, 3.0),
( 4.0, 5.0, 6.0),
( 7.0, 8.0, 9.0));
begin
put(A'First(1)); new_line;
put(A'Last(1));
end foo1;
-------------------------------
I think I Will go hunt for a book on Ada, and will
look at the packages Dmitry just posted.
thanks,
--Nasser
^ permalink raw reply [relevance 6%]
* Re: how to print an array range?
@ 2012-06-26 14:08 6% ` Nasser M. Abbasi
2012-06-26 14:24 6% ` Nasser M. Abbasi
0 siblings, 1 reply; 200+ results
From: Nasser M. Abbasi @ 2012-06-26 14:08 UTC (permalink / raw)
On 6/26/2012 8:54 AM, Georg Bauhaus wrote:
> On 26.06.12 15:47, Nasser M. Abbasi wrote:
>>
>> simple question from newbie. How do I print array range?
>
> A range is not a value of some type.
>
> For type T, print T'First and T'Last; for array A(..., ...),
> print A'First(n) and A'Last(n), n > 0 being the nth index type.
>
Ok fair enough.
btw, would you know by any chance why I get these values?
----------------------------------
with Ada.Text_Io; use Ada.Text_Io;
with Ada.Float_Text_Io; use Ada.Float_Text_Io;
with Ada.integer_Text_Io; use Ada.integer_Text_Io;
with Ada.Numerics.Real_Arrays; use Ada.Numerics.Real_Arrays;
procedure foo1 is
A : constant Real_Matrix :=
(( 1.0, 2.0, 3.0),
( 4.0, 5.0, 6.0),
( 7.0, 8.0, 9.0));
begin
put(A'First(1)); new_line;
put(A'Last(1));
end foo1;
----------------------------
>gnatmake foo1.adb
gcc-4.6 -c foo1.adb
gnatbind -x foo1.ali
gnatlink foo1.ali
>./foo1
-2147483648
-2147483646
>
I know I am doing something silly here.
(I feel I have so much catching to do with Ada)
--Nasser
^ permalink raw reply [relevance 6%]
* how to print an array range?
@ 2012-06-26 13:47 6% Nasser M. Abbasi
2012-06-28 6:59 0% ` Shark8
0 siblings, 2 replies; 200+ results
From: Nasser M. Abbasi @ 2012-06-26 13:47 UTC (permalink / raw)
simple question from newbie. How do I print array range?
I tried using image' attribute, but can't get the syntax to
work right.
----------------------------
with Ada.Text_Io; use Ada.Text_Io;
with Ada.Float_Text_Io; use Ada.Float_Text_Io;
with Ada.integer_Text_Io; use Ada.integer_Text_Io;
with Ada.Numerics.Real_Arrays; use Ada.Numerics.Real_Arrays;
procedure foo1 is
A : constant Real_Matrix :=
(( 1.0, 2.0, 3.0),
( 4.0, 5.0, 6.0),
( 7.0, 8.0, 9.0));
begin
put(A'range(1));
end foo1;
----------------------
I expected to see "1..3". How do you use image' on this
or other way to display the range?
thanks,
--Nasser
^ permalink raw reply [relevance 6%]
* Any easy/build-in construct to extract submatrices from larger matrix?
@ 2012-06-24 8:05 5% Nasser M. Abbasi
0 siblings, 0 replies; 200+ results
From: Nasser M. Abbasi @ 2012-06-24 8:05 UTC (permalink / raw)
Given square matrix, say 3 by 3 real matrix, and we
want to extract a submatrix from it, a 2 by 2 submatrix,
which is found by removing column and row given by
index I and J.
For example, given
A : constant Real_Matrix :=
(( 1.0, 2.0, 3.0),
( 4.0, 5.0, 6.0),
( 7.0, 8.0, 9.0));
and I=1, J=1, then the submatrix to extract is
5 6
8 9
because we removed row I=1, and column J=1, and what
is left is what is needed.
Ofcourse I can code it the hard way, using lots of if's,
and loops, and build the submatrix by hand, one row/column at
a time. But I wanted to see if there is a build-in
easy way, like slicing off a row and column off a matrix
on the fly.
Here is a skeleton code if someone wants to give this a try
---------------------------------------------
with Ada.Text_Io; use Ada.Text_Io;
with Ada.Float_Text_Io; use Ada.Float_Text_Io;
with Ada.Numerics.Real_Arrays; use Ada.Numerics.Real_Arrays;
procedure foo is
A : constant Real_Matrix :=
(( 1.0, 2.0, 3.0),
( 4.0, 5.0, 6.0),
( 7.0, 8.0, 9.0));
B : real_matrix(1 .. 2, 1 .. 2);
begin
FOR I in A'range(1) LOOP
FOR J in A'range(2) LOOP
--B := -- ??? smart way to do this?
put(A(I,J));
END LOOP;
new_line;
END LOOP;
end foo;
--------------------------------
fyi, modern Fortran has a nice facility to do this, called
pack(). It works like this: make up a MASK matrix of same size
as A. For those elements we want removed, put in a logical
.false at that location.
Hence, to extract column 1 say from A, build up a MASK matrix
with .false. in each element of the first column, then call
PACK() with this mask and A. Then PACK() return all elements
of A that has corresponding .true. in the MASK.
So, the above in Fortran works like this:
--------------------------------------------------
program t46
implicit none
integer, parameter :: n=3
integer :: i,j
real (kind=kind(0.0d0)) :: A(n,n),B(n-1,n-1)
logical :: mask(n,n)
A(1,:) = [1, 2, 3];
A(2,:) = [4, 5, 6];
A(3,:) = [7, 8, 9];
DO j=1,n
DO i=1,n
mask = .true.
mask(:,j) = .false.
mask(i,:) = .false.
!-- extract submatrix (looking for Ada equivalent)
B = reshape(pack(A, mask),[n-1,n-1])
write(*,'(2F6.1)') B
print *,'------------'
END DO
END DO
end program t46
------------------------------
>gfortran -fcheck=all -Wall t46.f90
>./a.out
5.0 8.0
6.0 9.0
------------
2.0 8.0
3.0 9.0
------------
2.0 5.0
3.0 6.0
------------
4.0 7.0
6.0 9.0
------------
1.0 7.0
3.0 9.0
------------
1.0 4.0
3.0 6.0
------------
4.0 7.0
5.0 8.0
------------
1.0 7.0
2.0 8.0
------------
1.0 4.0
2.0 5.0
------------
>
I have googled on-line looking for something build-in, but
so far, no luck. But will continue searching...
thanks,
--Nasser
^ permalink raw reply [relevance 5%]
* Re: questions on using the array component iterator for 2012
2012-06-23 12:02 5% questions on using the array component iterator for 2012 Nasser M. Abbasi
@ 2012-06-23 12:04 0% ` Nasser M. Abbasi
0 siblings, 0 replies; 200+ results
From: Nasser M. Abbasi @ 2012-06-23 12:04 UTC (permalink / raw)
On 6/23/2012 7:02 AM, Nasser M. Abbasi wrote:
> ---------------------------------------------
> with Ada.Numerics.Real_Arrays; use Ada.Numerics.Real_Arrays;
> procedure foo is
> A : constant Real_Matrix :=
> ( ( 1.0, 2.0, 3.0 ) ,
> ( 3.0, 5.0, 6.0 ) ,
> ( 7.0, 8.0, 9.0 ) );
> begin
> FOR e of A LOOP
> e := e + 1 ;
> END
> end Matrix_Product;
> ---------------------------------------------
>
opps, need to remove the 'constant' word above, so that A can be updated
ofocurse.
--Nasser
^ permalink raw reply [relevance 0%]
* questions on using the array component iterator for 2012
@ 2012-06-23 12:02 5% Nasser M. Abbasi
2012-06-23 12:04 0% ` Nasser M. Abbasi
0 siblings, 1 reply; 200+ results
From: Nasser M. Abbasi @ 2012-06-23 12:02 UTC (permalink / raw)
reference
http://www.ada-auth.org/standards/12rm/html/RM-5-5-2.html
The array component iterator seems nice, but I was not sure
if it can be used access elements in the matrix that are
indexed off the current iterator.
For example, assume I write
---------------------------------------------
with Ada.Numerics.Real_Arrays; use Ada.Numerics.Real_Arrays;
procedure foo is
A : constant Real_Matrix :=
( ( 1.0, 2.0, 3.0 ) ,
( 3.0, 5.0, 6.0 ) ,
( 7.0, 8.0, 9.0 ) );
begin
FOR e of A LOOP
e := e + 1 ;
END
end Matrix_Product;
---------------------------------------------
So the above adds '1' to each element in the matrix.
(order of iterations is defined in the RM, say I used
FORTRAN order).
But suppose I want to implement say a Jacobi relaxation
iteration to solve a 2D Laplace pde on that grid, which
is defined to update each element in the grid using
A(i) := (1/4) ( A(i-1,j)+A(i+1,j)+A(i,j-1)+A(i,j+1)
where here 'i' is row index, and 'j' is column index.
http://en.wikipedia.org/wiki/Relaxation_%28iterative_method%29
(iteration has to start from the second row and second column,
to avoid falling off the edge of the grid ofcourse, but this
is not important now)
i.e the above just replaces the current element in the matrix by
the average of the 4 adjacent elements in the little grid around
the current element.
My question is:
using 'e', this new iterator, can one somehow implement the above,
by somehow referencing these 4 adjacent elements in the grid?
(above, left, right, below)?
My point is that, if the iterator can be used only to access
the current element, then this might not be too useful.
For example, in the above example toy example, I do not
even need an iterator, I can use direct operation in Fortran or
Matlab say and just type
A = 1.0 + A
(I do not know if one can do this in Ada btw?) May be
one needs to just define a "+" function for this. (I am not
too experienced in Ada, will try it).
Thanks
--Nasser
^ permalink raw reply [relevance 5%]
* a bug in code shown in ada2012 rational or is it me?
@ 2012-06-20 10:09 5% Nasser M. Abbasi
0 siblings, 0 replies; 200+ results
From: Nasser M. Abbasi @ 2012-06-20 10:09 UTC (permalink / raw)
looking at
http://www.adacore.com/uploads/technical-papers/Ada2012_Rationale_Chp2_expressions.pdf
page 14. I translated that Ada function to Matlab and in Mathematica
and I am not getting the same value for Pi it shows. Not
even close.
I copied the Ada code from the PDF (hopefully all went ok) here
it is
--------------------------------------------
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Long_Long_Float_Text_IO;
use Ada.Long_Long_Float_Text_IO;
with Ada.Numerics.Long_Long_Elementary_Functions;
use Ada.Numerics.Long_Long_Elementary_Functions;
procedure Compute_Pi is
function B(N: Natural) return Long_Long_Float;
function A(N: Natural) return Long_Long_Float is
(if N = 0 then 1.0 else (A(N�1)+B(N�1))/2.0);
function B(N: Natural) return Long_Long_Float is
(if N = 0 then Sqrt(0.5) else Sqrt(A(N�1)*B(N�1)));
function T(N: Natural) return Long_Long_Float is
(if N = 0 then 0.25 else
(T(N�1)�2.0**(N�1)*A(N�1)�A(N))**2);
K: constant := 5; -- for example
Pi: constant Long_Long_Float := ((A(K) + B(K))**2 / (4.0*T(K));
begin
Put(Pi, Exp => 0);
New_Line;
end Compute_Pi;
-----------------------------
Here is the Matlab code translation. I tried to keep
all names of variables and functions the same
---- Matlab ---
function foo
format long
k=5;
(A(k)+B(k))^2/(4*T(k))
end
function r=A(n)
if n==0
r=1;
else
r=(A(n-1)+B(n-1))/2;
end
end
function r=B(n)
if n==0
r=sqrt(0.5);
else
r=sqrt(A(n-1)*B(n-1));
end
end
function r=T(n)
if n==0
r=0.25;
else
r=(T(n-1)-2^(n-1)*A(n-1)-A(n))^2;
end
end
-------------------------------
And here is the Mathematica code
-----------------------
b[n_]:=If[n==0,Sqrt[0.5],Sqrt[a[n-1]*b[n-1]]]
a[n_]:=If[n==0,1,(a[n-1]+b[n-1])/2]
t[n_]:=If[n==0,0.25,(t[n-1]-2^(n-1)*a[n-1]-a[n])^2]
k=5.;
(a[k]+b[k])^2/(4 t[k])
--------------------------------
Here is what I get
Out[9]= 0.0000847226845502729
Same with Matlab:
EDU>> foo
ans =
8.472268455027291e-05
I went over it many times, and I do not see what I copied
wrong. As far as I see, the translation maps to what is shown
in Ada.
I must have done something wrong in the translation? do you
see it? may be someone who has Ada 2012 can run this function
and see of it generates the value shown in the paper which is
3.14159265358979324
thanks,
--Nasser
^ permalink raw reply [relevance 5%]
* Re: Practicalities of Ada for app development
2012-06-13 0:04 4% ` Adam Beneschan
2012-06-13 3:04 0% ` Shark8
@ 2012-06-13 8:37 0% ` Georg Bauhaus
1 sibling, 0 replies; 200+ results
From: Georg Bauhaus @ 2012-06-13 8:37 UTC (permalink / raw)
On 13.06.12 02:04, Adam Beneschan wrote:
> Maybe this should be a challenge to the Ada community to come up with some common package specification (or set of packages) that would be sufficient to meet those needs, so that users wouldn't feel a need to switch to Perl to get the same kind of expressive power. Offhand, I don't think it would need to become part of the official language standard (the letters I, S, and O are not a magical incantation that automatically makes software more trustworthy). We've had working groups in the past that have developed standard packages that weren't part of the language (although some of them became part of later versions of the language, like Ada.Numerics). What does anyone else think? Does this seem worthwhile? I have to admit, I've sometimes been frustrated when I need to work with text, although not enough to get me to use Perl for more than smallish programs, so off the top of my head this seems like it might be useful.
I like the "sufficient for most needs" part very much. It allows
going back to just regular languages.
This is my wishlist for a framework supporting regular languages
built around language features familiar to Ada programmers:
1. The building blocks in Ada.Strings.Maps, Ada.Strings.Maps.Constants
etc seem to correspond to character classes in POSIX REs:
Hexadecimal_Digit_Set ~[0-9A-Fa-f]
Yet, the set operations of Maps exceed what I get in RE packages
of languages that start from version 7 regexp. Good!
So, alternation is presently possible for single characters.
Need groups and sequencing, expressed in the type system.
2. The container mechanics (Ada STL) offer one possible approach
to handling the set of matches:
The matching process results in an object of type that supports
iteration. Perhaps not just Cursors, but also Extended_Index
like in Vectors, because programmers will expect that
groups in patterns are indexed by number.
3. The pattern matching facilities need not go beyond
regular languages. Provide some frequently used constant
patterns, such as end-of-line, start-of-string, word-boundary.
4. Add a single, read-only feature for RE inspection. It allows
observing the scanning process:
For example, given (ABC|BCD)E, and a function "&" returning
a pattern type,
Alternation'(To_Set ("ABC") & To_Set ("BCD"))
& To_Pattern ("E");
Here, it might be helpful to see the backtracking (if any) triggered
when the scanner is about to hit "E". Therefore, allow programmers
to implement an abstract pattern type that matches the empty
string. The scanner will call its primitive subprogram,
thus
Alternation'(To_Set ("ABC") & To_Set ("BCD"))
& user_defined_empty_1
& To_Pattern ("E");
5. Define a small set of well chosen operators that reduce
verbosity. (GNAT's Spitbol.Patterns has quite a lot of them.)
6. Producing new text from input text should not physically rely
on Ada.Strings.Unbounded. Instead, allocate new strings that can
clean up after themselves.
In conclusion, programmers would rely on Ada's type system when expressing
a pattern. They would not be forced to write in yet another macro
language in strings, as is required by most scripting languages.
Access to matched portions of input uses a familiar framework.
^ permalink raw reply [relevance 0%]
* Re: Practicalities of Ada for app development
2012-06-13 0:04 4% ` Adam Beneschan
@ 2012-06-13 3:04 0% ` Shark8
2012-06-13 8:37 0% ` Georg Bauhaus
1 sibling, 0 replies; 200+ results
From: Shark8 @ 2012-06-13 3:04 UTC (permalink / raw)
On Tuesday, June 12, 2012 7:04:07 PM UTC-5, Adam Beneschan wrote:
> On Tuesday, June 12, 2012 2:12:53 PM UTC-7, Nomen Nescio wrote:
> > Adam Beneschan wrote:
> > >
> > > there are existing libraries to do such things in Ada. I think
> > > Vadim Godunko has a regular expression matcher
> >
> > Any high-level language can be expanded with libraries. This
> > capability doesn't offer a means to claim that the language itself is
> > good for all problems.
> >
> > One project might use Bob's String Parsing Machine (tm), while another
> > project becomes dependant on Vadim's Regex Swiss Army Knife (tm). So
> > you have the wheel reinvented in multiple styles, and developers who
> > cannot count on homogeneous interfaces being available as they move
> > from one project to the next. OTOH, you can count on developers to
> > know the language. IOW, what would otherwise be common knowledge
> > becomes tribal knowledge - knowledge that's lost with turnover. And
> > libs that are not held to the same standards and verification as the
> > compiler.
>
> Maybe this should be a challenge to the Ada community to come up with some common package specification (or set of packages) that would be sufficient to meet those needs, so that users wouldn't feel a need to switch to Perl to get the same kind of expressive power. Offhand, I don't think it would need to become part of the official language standard (the letters I, S, and O are not a magical incantation that automatically makes software more trustworthy). We've had working groups in the past that have developed standard packages that weren't part of the language (although some of them became part of later versions of the language, like Ada.Numerics). What does anyone else think? Does this seem worthwhile? I have to admit, I've sometimes been frustrated when I need to work with text, although not enough to get me to use Perl for more than smallish programs, so off the top of my head this seems like it might be useful.
>
> -- Adam
Good idea.
However, if it's a package devoted to text manipulation then we might want to use ropes rather than strings [ http://en.wikipedia.org/wiki/Rope_%28computer_science%29 ] and provide a To_String ana To_Unbounded_String functions. {I am assuming that it'll be a load-string, do-all-processing, store cycle with as few load/stores as possible.}
If it's allowed in 2012 perhaps something like:
GENERIC
Use_Ropes : Boolean:= True
PACKAGE Text_Possessing is
--...
END Text_Possessing;
WITH Rope_Implementation, String_Implementation;
PACKAGE BODY Text_Possessing is
Use (if Use_Ropes then Rope_Implementation else String_Implementation);
--...
END Text_Possessing;
^ permalink raw reply [relevance 0%]
* Re: Practicalities of Ada for app development
@ 2012-06-13 0:04 4% ` Adam Beneschan
2012-06-13 3:04 0% ` Shark8
2012-06-13 8:37 0% ` Georg Bauhaus
0 siblings, 2 replies; 200+ results
From: Adam Beneschan @ 2012-06-13 0:04 UTC (permalink / raw)
On Tuesday, June 12, 2012 2:12:53 PM UTC-7, Nomen Nescio wrote:
> Adam Beneschan wrote:
> >
> > there are existing libraries to do such things in Ada. I think
> > Vadim Godunko has a regular expression matcher
>
> Any high-level language can be expanded with libraries. This
> capability doesn't offer a means to claim that the language itself is
> good for all problems.
>
> One project might use Bob's String Parsing Machine (tm), while another
> project becomes dependant on Vadim's Regex Swiss Army Knife (tm). So
> you have the wheel reinvented in multiple styles, and developers who
> cannot count on homogeneous interfaces being available as they move
> from one project to the next. OTOH, you can count on developers to
> know the language. IOW, what would otherwise be common knowledge
> becomes tribal knowledge - knowledge that's lost with turnover. And
> libs that are not held to the same standards and verification as the
> compiler.
Maybe this should be a challenge to the Ada community to come up with some common package specification (or set of packages) that would be sufficient to meet those needs, so that users wouldn't feel a need to switch to Perl to get the same kind of expressive power. Offhand, I don't think it would need to become part of the official language standard (the letters I, S, and O are not a magical incantation that automatically makes software more trustworthy). We've had working groups in the past that have developed standard packages that weren't part of the language (although some of them became part of later versions of the language, like Ada.Numerics). What does anyone else think? Does this seem worthwhile? I have to admit, I've sometimes been frustrated when I need to work with text, although not enough to get me to use Perl for more than smallish programs, so off the top of my head this seems like it might be useful.
-- Adam
^ permalink raw reply [relevance 4%]
* Re: Arctan: to use with single or with double arguments?
@ 2012-02-11 16:47 6% ` Simon Wright
0 siblings, 0 replies; 200+ results
From: Simon Wright @ 2012-02-11 16:47 UTC (permalink / raw)
Georg Bauhaus <rm.dash-bauhaus@futureapps.de> writes:
> On 11.02.12 16:29, Simon Wright wrote:
>> AdaMagica<christ-usch.grein@t-online.de> writes:
>>
>>> It's a severe bug to use positional association for Arctan!
>>
>> Only a bug if you get it wrong. Otherwise it's a meta-bug.
>>
>> Not sure that Arctan (Y => X, X => Y) is exactly _clear_.
>
> No clarity at all when the brain switches between coordinate
> system conventions, row or column major order, and similar
> non-Ada ways of expressing things. Since the semantics of
> any program calling Arctan is not changed if the parameter
> name X becomes <<unambiguously-denoting-what-we-mean>>, thus
> since there will be an absolutely safe change set if such
> a name were introduced, isn't it about time to get rid of
> names that only a high school delusion holds up against?
In Ada2012,
with Ada.Numerics.Elementary_Functions;
package Naval_Angles is
function Bearing (Northings : Float;
Eastings : Float) return Float is
(Ada.Numerics.Elementary_Functions.Arctan (Y => Eastings,
X => Northings));
end Naval_Angles;
(not sure that 'bearing' is the right word, since the same coordinate
system is used for 'heading' and 'course' ...)
^ permalink raw reply [relevance 6%]
* Re: Basic question on Ada multi-dimensional arrays, are they true (contiguous) arrays? aliasing rules?
2011-12-21 21:11 4% ` Adrian-Ken Rueegsegger
@ 2011-12-21 21:13 4% ` Adrian-Ken Rueegsegger
1 sibling, 0 replies; 200+ results
From: Adrian-Ken Rueegsegger @ 2011-12-21 21:13 UTC (permalink / raw)
On 12/21/2011 02:08 AM, Nasser M. Abbasi wrote:
> Sorry for such a basic question on Ada, it has been a while since
> I used Ada (but it remains my most favorite computer language).
[snip]
> Are there are benchmarks comparing Ada for Fortran in this specific area?
This is just barely related but maybe it is still of interest to you: as
part of writing the CUDA/Ada binding [1] I did some benchmarking of
matrix operations (addition and multiplication) using the
Ada.Numerics.Real_Arrays package. I compared the native Ada
implementation ("*"-operator), doing the multiplication on the GPU using
the CUDA/Ada binding and a native CUDA C implementation.
We are in the middle of finishing up the article documenting CUDA/Ada
which will contain a section analyzing the performance measurements. The
main focus is on the potential performance penalty of CUDA/Ada vs native
CUDA C though so as mentionend in the beginning this is probably
tangential to your question...
Cheers,
Adrian
--
[1] - http://www.codelabs.ch/cuda-ada/
^ permalink raw reply [relevance 4%]
* Re: Basic question on Ada multi-dimensional arrays, are they true (contiguous) arrays? aliasing rules?
@ 2011-12-21 21:11 4% ` Adrian-Ken Rueegsegger
2011-12-21 21:13 4% ` Adrian-Ken Rueegsegger
1 sibling, 0 replies; 200+ results
From: Adrian-Ken Rueegsegger @ 2011-12-21 21:11 UTC (permalink / raw)
On 12/21/2011 02:08 AM, Nasser M. Abbasi wrote:
> Sorry for such a basic question on Ada, it has been a while since
> I used Ada (but it remains my most favorite computer language).
[snip]
> Are there are benchmarks comparing Ada for Fortran in this specific area?
This is just barely related but maybe it is still of interest to you: as
part of writing the CUDA/Ada binding [1] I did some benchmarking of
matrix operations (addition and multiplication) using the
Ada.Numerics.Real_Arrays package. I compared the native Ada
implementation ("*"-operator), doing the multiplication on the GPU using
the CUDA/Ada binding and a native CUDA C implementation.
We are in the middle of finishing up the article documenting CUDA/Ada
which will contain a section analyzing the performance measurements. The
main focus is on the potential performance penalty of CUDA/Ada vs native
CUDA C though so as mentionend in the beginning this is probably
tangential to your question...
Cheers,
Adrian
--
[1] - http://www.codelabs.ch/cuda-ada/
^ permalink raw reply [relevance 4%]
* Re: Iterators in Ada2012
2011-11-09 10:55 4% ` Georg Bauhaus
@ 2011-11-25 14:20 0% ` Yannick Duchêne (Hibou57)
0 siblings, 0 replies; 200+ results
From: Yannick Duchêne (Hibou57) @ 2011-11-25 14:20 UTC (permalink / raw)
Le Wed, 09 Nov 2011 11:55:52 +0100, Georg Bauhaus
<rm-host.bauhaus@maps.futureapps.de> a écrit:
> Me neither; though Ada.Numerics.*Random are examples of how
> to model producing elements on demand. I imagine one can do similar
> things with task objects in order to emulate a Python style yield.
> The result, then, is a generating mechanism that does not require
> a working set in memory. I guess one could make the mechanism
> more generically useful.
>
> task body Generator is
> Current : Value_Type;
> begin
> loop
> Current := Produce_Next;
> accept Next (Result : out Value_Type) do
> Result := Current;
> end Next;
> end loop;
> end Generator;
The good time for a question: Are coroutines planned for Ada 2020 ?
--
“Syntactic sugar causes cancer of the semi-colons.” [1]
“Structured Programming supports the law of the excluded muddle.” [1]
[1]: [Epigrams on Programming — Alan J. — P. Yale University]
^ permalink raw reply [relevance 0%]
* Re: Iterators in Ada2012
@ 2011-11-09 10:55 4% ` Georg Bauhaus
2011-11-25 14:20 0% ` Yannick Duchêne (Hibou57)
0 siblings, 1 reply; 200+ results
From: Georg Bauhaus @ 2011-11-09 10:55 UTC (permalink / raw)
On 11/9/11 5:12 AM, R. Tyler Croy wrote:
> Additionally, generator expressiones: `(x for x in iterable)` are lazily
> evaluated so you don't have to actually have your working set in memory
> all at once.
Maybe it is worth mentioning---though in this case savings come from the
other end where collections exist---that Iterate may not have to
inspect every element. Exceptions such as StopIteration in the following
example, can make the process stop early, as needed:
with Ada.Containers.Ordered_Maps;
with Ada.Text_IO;
procedure Iter is
type Location is digits 8;
type Coords is record
Sun : Location;
Snow : Location;
end record;
type Place is (Nowhere, Springfield, Shangri_La, Meryton, Zamunda);
package Maps is new Ada.Containers.Ordered_Maps
(Key_Type => Place,
Element_Type => Coords);
StopIteration : exception;
Whereabouts : Maps.Map;
First_Above_Equator : Place;
procedure Is_Above (Key : Place; Element : Coords) is
-- When place `Key` is above the equator, stores it in
-- `First_Above_Equator` and raises `StopIteration`
begin
if Element.Snow > 0.0 then
First_Above_Equator := Key;
raise StopIteration;
end if;
end Is_Above;
procedure Stops_Early (Position : Maps.Cursor) is
-- inspects key/element via `Is_Above`
begin
Maps.Query_Element (Position, Is_Above'Access);
end Stops_Early;
begin
First_Above_Equator := Nowhere;
Whereabouts.Insert (Meryton, Coords'(Sun => 0.0, Snow => 51.0));
-- ...
Whereabouts.Iterate (Stops_Early'Access);
exception
when StopIteration =>
Ada.Text_IO.Put_Line (Place'Image (First_Above_Equator));
end Iter;
> An Ada "built-in" equivalent of a generator expression I actually don't
> know of,
Me neither; though Ada.Numerics.*Random are examples of how
to model producing elements on demand. I imagine one can do similar
things with task objects in order to emulate a Python style yield.
The result, then, is a generating mechanism that does not require
a working set in memory. I guess one could make the mechanism
more generically useful.
task body Generator is
Current : Value_Type;
begin
loop
Current := Produce_Next;
accept Next (Result : out Value_Type) do
Result := Current;
end Next;
end loop;
end Generator;
And wrap it in an Ada.Container like package.
^ permalink raw reply [relevance 4%]
* Re: organizing deep source trees with child packages
2011-10-19 9:03 3% ` Dmitry A. Kazakov
2011-10-19 9:52 0% ` Ludovic Brenta
@ 2011-10-20 10:50 0% ` Stephen Leake
1 sibling, 0 replies; 200+ results
From: Stephen Leake @ 2011-10-20 10:50 UTC (permalink / raw)
"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
>>> Generics also adds a layer of indirection instance <-> generic-body.
>>> It is just impossible to remember which is an instance of what and
>>> where are instances with particular parameters.
>>
>> Why is it necessary to _remember_ that?
>
> In order to find it. E.g. let you have the type Loudness and for some
> reason need a logarithm of its value. You remember that you have already
> instantiated Ada.Numerics.Elementary_Functions with Loudness as the
> parameter somewhere, but need to remember the package name in order to
> "with" it. You probably instantiated Float_IO too, where it was?
>
> Now that was just a trivial example for which some naming schema could
> easily be deployed in order to help with that.
Yes, that is the solution, and it works for the non-trivial real
projects I work on. I have rules for naming generics, and for placing
them in the proper directories, so everyone can find them.
>> That doesn't mean we can't have a technical discussion, to understand
>> what the issues are, and how to improve both Emacs and GPS to make them
>> both better.
>
> Not really, because to me the starting point for such discussion is the
> precondition that an *Ada IDE* shall show *Ada* projects, *Ada* units,
> *Ada* types, not files.
You are presupposing the solution, which makes it impossible to discuss
the rationale for that solution.
> It seems that Emacs users disagree with this precondition telling me
> how exciting it is to find|grep directories.
I never said it was "exciting". I simply offered that as one possible
solution, to one particular problem. In fact, I presented find|grep as
an undesirable solution, and presented better ones.
In order to have a useful discussion, you need to actively search for
areas of agreement; we agree that find|grep is not a very good solution.
I do disagree that an IDE should work only for one particular language.
I have never worked on any project that was 100% pure Ada, or any other
language. There are always documents written in LaTeX or other formats,
small bits of interface code written in other languages, Makefiles,
compiler configuration files, web pages, and other files that I need to
access. I much prefer using one IDE to do all of that, rather than
switching between IDEs based on the file type. Since the basic tasks are
"find the right file" and "change the text in it", most of the IDE
functionality is shared among the file types. Learning how to use one
IDE well is far more effiicient than learning how to use several IDEs.
--
-- Stephe
^ permalink raw reply [relevance 0%]
* Re: organizing deep source trees with child packages
2011-10-19 9:03 3% ` Dmitry A. Kazakov
@ 2011-10-19 9:52 0% ` Ludovic Brenta
2011-10-20 10:50 0% ` Stephen Leake
1 sibling, 0 replies; 200+ results
From: Ludovic Brenta @ 2011-10-19 9:52 UTC (permalink / raw)
Dmitry A. Kazakov wrote on comp.lang.ada:
> My answer to this question was: I would not care about the convention if
> the IDE showed me Ada units. Since the IDE, I am using (GPS), shows file
> names, I would prefer a convention which eliminates as much as possible of
> the mess introduced by the file system.
I agree with this.
> My guess is that the Java
> convention would possibly do it better than the GNAT convention.
Here you are contradicting yourself; you think that introducing more
of the "mess introduced by the filesystem" will fix the problem. It
won't. Placing all of your source files in one, or a few, directories
will not solve the problem either, but at least it will not make it
worse.
> But again, if the IDE showed units in their relationships (parent-child,
> generic-instance, parent-separate body) rather than files, the problem
> would disappear.
Correct. In my daily usage, I almost never have to browse a
filesystem because my IDE (Emacs) allows me to navigate the code
efficiently.
>> I vote for the gnat convention, because the mapping is trivial, and
>> directories are a pain.
>
> Yes, they are when the tools are feeble. With proper tools you would not
> care.
But you will always have to use a feeble tool at one point or
another. Think of version control systems, backup systems, pretty-
printers, find+grep, etc. which do not know, or want to know, about
file naming conventions or the semantics of Ada. For these tools,
keeping the filesystem layout simple is better. Granted, the tools I
mentioned are not "feeble" but making them work in the presence of
multiple levels of directories is an additional and unnecessary
hassle.
>>> Generics also adds a layer of indirection instance <-> generic-body.
>>> It is just impossible to remember which is an instance of what and
>>> where are instances with particular parameters.
>
>> Why is it necessary to _remember_ that?
>
> In order to find it. E.g. let you have the type Loudness and for some
> reason need a logarithm of its value. You remember that you have already
> instantiated Ada.Numerics.Elementary_Functions with Loudness as the
> parameter somewhere, but need to remember the package name in order to
> "with" it. You probably instantiated Float_IO too, where it was?
The software I work on has been in existence for much longer than my
presence here. I cannot possibly remember generic instantiations made
ten years ago by someone else but I can easily find them using
gnatfind, which is integrated in emacs. I simply do C-c C-r on the
spec of the generic and I can discover all instantiations of it. In
fact I have already removed some redundant instantiations after
discovering them that way. Remembering all of the code is not my job;
my job is to *understand* the code. I have excellent tools that do
the remembering for me.
> Now that was just a trivial example for which some naming schema could
> easily be deployed in order to help with that. I am talking about projects
> which *do* use generics, of multiple generic parameters, child generic
> units etc.
A file naming scheme does not help with generic instantiations because
some generic instantiations are nested in other units and therefore
not in a file of their own.
>> What does this have to do with file names?
>
> Each generic instance is located in some file.
Yes but there is absolutely no correspondence between the name of the
file, the name of the generic instantiation, or the name of the
generic itself. Especially with generic instantiations inside package
bodies or even inside subprograms (e.g. passive iterators). Also, one
file can contain multiple generic instantiations. Therefore, no
naming convention can help discover or find generic instantiations.
Only semantic navigation can.
> Not really, because to me the starting point for such discussion is the
> precondition that an *Ada IDE* shall show *Ada* projects, *Ada* units,
> *Ada* types, not files. It seems that Emacs users disagree with this
> precondition telling me how exciting it is to find|grep directories.
I am an emacs user an I am telling you exactly the opposite. Emacs is
great at hiding the very existence of files because its semantic
browsing capabilities are outstanding. Because of this, "organizing"
files in multiple directories gives zero benefit to emacs, but is a
nuisance for some other tools, which we *also* have to use from time
to time. Since, of course, emacs users launch these other tools from
emacs, it is quite natural that, when they do occasionally need to
browse a file system, they should prefer a very simple directory
layout, and should not be afraid, or surprised, to see hundreds, even
thousands of files in the same directory.
--
Ludovic Brenta.
^ permalink raw reply [relevance 0%]
* Re: organizing deep source trees with child packages
@ 2011-10-19 9:03 3% ` Dmitry A. Kazakov
2011-10-19 9:52 0% ` Ludovic Brenta
2011-10-20 10:50 0% ` Stephen Leake
0 siblings, 2 replies; 200+ results
From: Dmitry A. Kazakov @ 2011-10-19 9:03 UTC (permalink / raw)
On Tue, 18 Oct 2011 21:51:15 -0400, Stephen Leake wrote:
> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
>
>> On Tue, 18 Oct 2011 07:12:03 -0400, Stephen Leake wrote:
>>
>>>>> When do file names and package names _need_ to be different?
>>>>
>>>> Always.
>>>
>>> Why? Simple assertions don't get us anywhere.
>>
>> "c:\mess\foo.adb" /= "Foo"
>
> You seem to be deliberately misrepresenting the question.
What was the question so was the answer, the package name is always
different from its file name.
> No one is
> talking about the absolute path as "the file name"; we are only talking
> about the part of the path that maps to the Ada package name.
>
> So far, the choices seem to be:
>
> package name Foo.Bar.Baz
> gnat convention foo-bar-baz.ads
> "java" foo/bar/baz.ads
> gnatkr f-barbaz.ads
> something else fobaba.ads
>
> Which of these is best, and why?
My answer to this question was: I would not care about the convention if
the IDE showed me Ada units. Since the IDE, I am using (GPS), shows file
names, I would prefer a convention which eliminates as much as possible of
the mess introduced by the file system. My guess is that the Java
convention would possibly do it better than the GNAT convention.
But again, if the IDE showed units in their relationships (parent-child,
generic-instance, parent-separate body) rather than files, the problem
would disappear.
> I vote for the gnat convention, because the mapping is trivial, and
> directories are a pain.
Yes, they are when the tools are feeble. With proper tools you would not
care.
>> Generics also adds a layer of indirection instance <-> generic-body.
>> It is just impossible to remember which is an instance of what and
>> where are instances with particular parameters.
>
> Why is it necessary to _remember_ that?
In order to find it. E.g. let you have the type Loudness and for some
reason need a logarithm of its value. You remember that you have already
instantiated Ada.Numerics.Elementary_Functions with Loudness as the
parameter somewhere, but need to remember the package name in order to
"with" it. You probably instantiated Float_IO too, where it was?
Now that was just a trivial example for which some naming schema could
easily be deployed in order to help with that. I am talking about projects
which *do* use generics, of multiple generic parameters, child generic
units etc.
> What does this have to do with
> file names?
Each generic instance is located in some file.
>>>> The point is, when browsing a project you are not interested in files,
>>>
>>> Depends on exactly why I'm "browsing".
>>
>> While programming/reviewing/testing/debugging an Ada program.
>
> Still not specific enough. What demands do the various activities place
> on the browser?
Because you cannot see all units of the project at once, not even their
names.
> That doesn't mean we can't have a technical discussion, to understand
> what the issues are, and how to improve both Emacs and GPS to make them
> both better.
Not really, because to me the starting point for such discussion is the
precondition that an *Ada IDE* shall show *Ada* projects, *Ada* units,
*Ada* types, not files. It seems that Emacs users disagree with this
precondition telling me how exciting it is to find|grep directories.
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
^ permalink raw reply [relevance 3%]
* Re: sharp ß and ss in Ada keywords like AC CESS
@ 2011-10-13 13:25 3% ` Dmitry A. Kazakov
0 siblings, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2011-10-13 13:25 UTC (permalink / raw)
On Thu, 13 Oct 2011 14:13:36 +0200, Georg Bauhaus wrote:
> On 13.10.11 10:10, Dmitry A. Kazakov wrote:
>
>> How is "acceβ" worse than "acceß"?
>
> The first identifier mixes two different "alphabets";
> The second identifier uses variant spelling.
> The second identifier can be changed without debate.
> This is how "acceβ" worse than "acceß".
Not convincing. It refers to "alphabets" and "spellings". Why should
anybody care about them?
> The first identifier, mixing two "alphabets", is
> like a literal mixing Roman numerals and Arabic numerals
> to form a single numeric literal:
>
> Some_Year : constant := MCD92;
>
> Yeah, that's fun. And there are no Chinese digits
> in it, so Europeans and Americans will likely recognize the
> intent.
Motor control device, the model of the year 1992?
> But otherwise? What's the point when mixing two
> numeric alphabets?
9 and 2 are not letters. What is the point to mix them at all? E.g. in
"I2"? I don't care if I2 is improperly spelt in any natural language.
>>>> type Acceß_Type is access Integer;
>>>> type Access_Type is access String;
>>>
>>> I'd prefer them to be the same in this particular
>>> case, since the Swiss model (which is without ß)
>>> is working.
>>
>> What is the reason for them to be same?
>
> "the Swiss model (which is without ß) is working."
I bet 90% of Ada users could not care less.
>> How do you know in which alphabet is "Mass"? Why should it conflict with
>> "Maß" for some French programmer?
>
> The identifiers shouldn't be in conflict, but Ada
> makes them be in conflict, Randy has stated one reason.
>
> I can think of two reasons for ss = ß but I /= І:
>
> 1) I /= І, since they are from "alphabets" that real people
> think are different.
Show me one, who thinks they are different without hexadecimal editor.
> To make the example less artificial,
> Let Αδα /= Ada. Put your projects at risk and hire
> programmers who would write Aδα (A["03B4"]["03B1"]).
> The compiler will help you finding them out.
If some nonsensical language rules put projects at risk, then, maybe, there
is something wrong with these rules?
> 2) ss = ß because real people think and act as though
> they are the same, and, importantly, more so (note
> the non-binary, comparative phrase) WRT ss = ß than
> WRT ä = ae, since absence of ä is considered a computer
> thingy, but equivalence of ss and ß is well established
> with or without computer. It is a different issue.
Real people also think that sch=sh, kn=n (at the beginning of the word),
oo=u, ee=i and ad infinitum.
> "Mass" has four Latin characters, "Maß" has three,
So why are they equivalent?
>> If "Latin" does not mean Latin, then you need yet another nonsensical rule
>> to redefine it.
>
> "Latin" is here meant to refer to the general thing.
> "Latin characters used in Europe" is pretty clear,
Does this include Greece, Serbia, Bulgaria?
> and no one will sue you if you include ä or ł.
That must the reason? No one could if I exclude them and ß too.
> Declaring simple unions of sections from Unicode is easy,
> and consistent.
Again, what is the rationale? It is quite easy to jump out of the 10th
floor window. There result will be very consistent too. Why should anybody
do this?
>> Who are these people?
>
> The people who influence standards.
Sure, who would care about users of the standards... (:-))
>>> If a word looks like a mix of Cyrillic characters,
>>
>> You cannot see characters, you do glyphs.
>
> That's techno-speak again, but programmers see characters
> if you ask them.
Nope, it is a physiological fact that people see glyphs.
>> You cannot
>> safely recognize alphabet looking at a single word.
>
> I am looking at programs, not at single words.
Does this mean that a program may not use several alphabets? Great, the
package Ada.Numerics is illegal. I always knew it!
>>> A programmer
>>> seeing Cyrillic characters will, on average, be
>>> right in assuming that he is seeing some
>>> identifier written in some Slavic language.
>>
>> Program legality based on statistic analysis? That must be a lot of fun!
>
> We employ tons of statistics when reading text.
This has nothing to do with the validity of such texts. I don't care about
Swiss model, I do about separate compilation. I don't want the legality of
components (tested, verified, validated) be randomly dependent on other
parts by mere placing them into one project.
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
^ permalink raw reply [relevance 3%]
* Re: fixed point vs floating point
@ 2011-10-01 13:37 4% ` RasikaSrinivasan@gmail.com
0 siblings, 0 replies; 200+ results
From: RasikaSrinivasan@gmail.com @ 2011-10-01 13:37 UTC (permalink / raw)
in embedded platforms, it is not often we have a floating point
processor (or it may come at a price which we cannot afford!) and they
have to be emulated. fixed point arithmetic may do the job in certain
class of problems. in my class of problems, i am not sure the fixed
point arithmetic will be sufficient. the experiments are to understand
how the fixed point solutions may diverge from the floating point
solutions.
but the basic answer appears to be that the ada generics makes it a
tiny bit harder to do this - but unfortunately renders ADa.Numerics.*
also not a viable option for fixed point data types.
thanks for the insights, srini
On Sep 30, 6:17 am, Stephen Leake <stephen_le...@stephe-leake.org>
wrote:
> "RasikaSriniva...@gmail.com" <rasikasriniva...@gmail.com> writes:
> > friends
>
> > I am investigating the applicability of fixed point to a numerical
> > problem. I would like to develop the algorithm as a generic and test
> > with different floating and fixed point types to decide which one to
> > go with.
>
> What sort of criteria are you using to make the decision?
>
> If it's just speed, then the answer will depend more on the hardware and
> the level of compiler optimization than on this choice.
>
> The major algorithmic difference between fixed and floating is the
> handling of small differences; floating point allows arbitrarily small
> differences (down to the exponent limit, of course), while fixed point
> has a fixed small difference.
>
> So the choice should be determined by the application, not by
> experiment.
>
> The only place I have found fixed point to be useful is for time;
> everything else ends up needing to be scaled, so it might as well be
> floating point from the beginning.
>
> The other thing that can determine the choice is the hardware; if you
> have no floating point hardware, you will most likely need fixed point.
> But even then, it depends on your speed requirement. You can do floating
> point in software; it's just slower than fixed point on the same hardware.
>
> > - can we design a generic (function or procedure) that can accept
> > either fixed point or floating point data types at the same time
> > excluding other types
>
> No.
>
> --
> -- Stephe
^ permalink raw reply [relevance 4%]
* fixed point vs floating point
@ 2011-09-29 10:25 5% RasikaSrinivasan@gmail.com
0 siblings, 1 reply; 200+ results
From: RasikaSrinivasan@gmail.com @ 2011-09-29 10:25 UTC (permalink / raw)
friends
I am investigating the applicability of fixed point to a numerical
problem. I would like to develop the algorithm as a generic and test
with different floating and fixed point types to decide which one to
go with.
Questions:
- ada.numerics family is pretty much floating point only - is this
correct?
- can we design a generic (function or procedure) that can accept
either fixed point or floating point data types at the same time
excluding other types
thanks for hints/pointers,
srini
^ permalink raw reply [relevance 5%]
* Re: Eigenvalues to find roots of polynomials
@ 2011-07-26 15:40 7% ` marius63
0 siblings, 0 replies; 200+ results
From: marius63 @ 2011-07-26 15:40 UTC (permalink / raw)
And the winner is...
> <http://home.roadrunner.com/~jbmatthews/misc/groots.html>
John B. Matthews Ada...Generic_Roots works like a charm.
It passed the simple test case, and solved my quintic problem x^5 -
4178x + 4177
$ ./find_roots_mathews 1 0 0 0 -4178 4177
Index => 0, Position => 6, Value => 4177
Index => 1, Position => 5, Value => -4178
Index => 2, Position => 4, Value => 0
Index => 3, Position => 3, Value => 0
Index => 4, Position => 2, Value => 0
Index => 5, Position => 1, Value => 1
Root 1 => (Re=> 1.00000000000000E+00, Im=> 0.00000000000000E+00)
Root 2 => (Re=>-2.47582467311450E-01, Im=>-8.05881611194044E+00)
Root 3 => (Re=> 7.76752669636581E+00, Im=>-1.40129846432482E-45)
Root 4 => (Re=>-2.47582467311450E-01, Im=> 8.05881611194044E+00)
Root 5 => (Re=>-8.27236176174291E+00, Im=> 0.00000000000000E+00)
I know from previous mathematical derivation (the polynomial comes
from extracting a variable in a summation), that the solution is a non-
negative scalar different from one, so Root 3 is my number, with the
non-zero but very small value of the imaginary part certainly only a
residue of computation done inside Matthews's magic machine. Thanks a
very great lot. Source code follows. Sorry for the mispelling,
"Mathews".
-- Trying to compute the roots of a polynomial using John Mathews
procedure.
with Ada.Command_Line;
with Ada.Numerics.Generic_Real_Arrays;
with Ada.Text_IO;
with Ada.Numerics.Generic_Complex_Types;
with Ada.Numerics.Generic_Complex_Arrays;
with Ada.Numerics.Generic_Complex_Arrays.Generic_Roots;
procedure Find_Roots_Mathews is
type Real is digits 15;
package Real_Arrays is new Ada.Numerics.Generic_Real_Arrays (Real);
package Complex_Types is new Ada.Numerics.Generic_Complex_Types
(Real);
package Complex_Arrays is new Ada.Numerics.Generic_Complex_Arrays
(Real_Arrays, Complex_Types);
procedure Complex_Roots is new Complex_Arrays.Generic_Roots;
M, N : Natural;
begin
M := Ada.Command_Line.Argument_Count;
N := M - 1;
-- N = number of arguments = degree of the polynomial + 1.
-- The input consists of all coficients in descending degree,
-- e.g. for polynomial
-- x^3 - 2x^2 - x + 2
-- the input is
-- 1 -2 -1 2
-- Roots of the above (for testing):
-- -1, 1, 2
declare
P : Complex_Arrays.Complex_Vector (0 .. N);
R : Complex_Arrays.Complex_Vector (1 .. N);
use Ada.Text_IO;
begin
for I in 0 .. N loop
Put_Line ("Index => " & I'img &
", Position => " & Integer'Image(M - I) &
", Value => " & Ada.Command_Line.Argument (M - I));
P (I) := (Re => Real'Value (Ada.Command_Line.Argument (M -
I)), Im => 0.0);
end loop;
Complex_Roots (P, R);
for I in R'Range loop
Put_Line ("Root" & I'img &
" => (Re=>" & R(I).Re'img &
", Im=>" & R(I).Im'img & ")");
end loop;
end;
end;
^ permalink raw reply [relevance 7%]
* Eigenvalues to find roots of polynomials
@ 2011-07-25 17:36 7% marius63
0 siblings, 1 reply; 200+ results
From: marius63 @ 2011-07-25 17:36 UTC (permalink / raw)
I am trying to use Eigenvalues methods to find the roots of
polynomials... and failing miserably!
My math ability is not stellar. I used the information at
(1)
http://mathworld.wolfram.com/PolynomialRoots.html (equation 12)
and
(2)
http://en.wikipedia.org/wiki/Root_finding
(One possibility is to form the companion matrix of the polynomial.
Since the eigenvalues of this matrix coincide with the roots of the
polynomial, one can use any eigenvalue algorithm to find the roots of
the polynomial.)
http://en.wikipedia.org/wiki/Companion_matrix
I tried both schemes with the test data in (1). The output is first
the matrix, for verification, then the (wrong) roots (they should be
-1, 1, 2) and the result of applying them to the polynomial (and
yielding miserably non-zero values of course). The source code
follows. What am I missing? Thanks a lot.
$ ./find_roots 1 -2 -1 2
5.00000E-01 1.00000E+00-5.00000E-01
1.00000E+00 0.00000E+00 0.00000E+00
0.00000E+00 1.00000E+00 0.00000E+00
-7.6156E-01=> 4.2003E-01
4.1249E+00=>-1.6015E+01
6.3667E-01=> 5.9465E-01
$ ./find_roots_wikipedia -2 -1 2
0.00000000000000E+00, 0.00000000000000E+00, -2.00000000000000E+00,
1.00000000000000E+00, 0.00000000000000E+00, 1.00000000000000E+00,
0.00000000000000E+00, 1.00000000000000E+00, 2.00000000000000E+00,
-1.17008648662603E+00 => -3.38499151386795E-02
6.88892182534018E-01 => 1.96496630422799E+00
2.48119430409202E+00 => 3.00688836109107E+01
-- Trying to compute the roots of a polynomial using the method
-- described in eq. (12) of http://mathworld.wolfram.com/PolynomialRoots.html
-- (consulted July 2011)
with Ada.Command_Line;
with Ada.Numerics.Generic_Real_Arrays;
with Ada.Text_IO;
with Ada.Numerics.Generic_Complex_Types;
with Ada.Numerics.Generic_Complex_Arrays;
procedure Find_Roots is
type Real is digits 5;
package Real_Arrays is new Ada.Numerics.Generic_Real_Arrays (Real);
package Complex_Types is new Ada.Numerics.Generic_Complex_Types
(Real);
package Complex_Arrays is new Ada.Numerics.Generic_Complex_Arrays
(Real_Arrays, Complex_Types);
N, M : Natural;
begin
N := Ada.Command_Line.Argument_Count;
-- N = number of arguments = degree of the polynomial.
-- The input consists of all coficients in descending degree,
-- e.g. for polynomial
-- x^3 - 2x^2 - x + 2
-- the input is
-- 1 -2 -1 2
-- Roots of the above (for testing):
-- -1, 1, 2
declare
C : Complex_Arrays.Complex_Matrix (1 .. N - 1, 1 .. N - 1) :=
(others => (others => (0.0, 0.0)));
-- Using a complex matrix because real matrices for eigenvalues
must be symmetric.
-- Below we convert all real values to complex (with null Im
part).
-- The complex matrix must be Hamiltonian;
-- I thought a non-symmetric converted to complex would
-- yield a non-Hamiltonian matrix, but I tried and it
worked :-)... hmm... NOT :-(
A0 : Real := Real'Value (Ada.Command_Line.Argument (N));
use Ada.Text_IO;
begin
for I in 1 .. N - 1 loop
C (1, I).Re := - Real'Value (Ada.Command_Line.Argument (N -
I)) / A0;
if I < N - 1 then
C (I + 1, I).Re := 1.0;
end if;
end loop;
-- inspect matrix
for i in c'range(1) loop
for j in c'range(2) loop
put (c(i,j).re'img);
end loop;
new_line;
end loop;
declare
V : Real_Arrays.Real_Vector := Complex_Arrays.Eigenvalues
(C);
use Real_Arrays;
Z : Real;
use Ada.Text_IO;
begin
for I in V'Range loop
V (I) := 1.0 / V (I);
Put (Real'Image (V (I)));
Z := 0.0;
for J in 1 .. N - 1 loop
Z := Z + C (1, J).Re * V (I) ** J;
end loop;
Put ("=>" & Real'Image (Z));
New_Line;
end loop;
end;
end;
end;
-- Build with:
-- gnatmake find_roots -largs /Developer/SDKs/MacOSX10.4u.sdk/usr/lib/
libblas.dylib /Developer/SDKs/MacOSX10.4u.sdk/usr/lib/liblapack.dylib
-- Given an Nth degree polynomial A(N)X**N + ... + A(1)X + A(0),
-- the roots can be found by finding the eigenvalues L(I) of the
matrix
-- _ _
-- | -A(1)/A(0) -A(2)/A(0) -A(3)/A(0) ... -A(N)/A(0) |
-- | 1 0 0 ... 0 |
-- | 0 1 0 ... 0 |
-- | ... ... 1 ... 0 |
-- |_ 0 0 0 ... 0 _|
--
-- and taking R(i) = 1/L(I). This method can be computationally
expensive,
-- but is fairly robust at finding close and multiple roots.
-- (wolphram)
-- This program computes the roots of a polynomial using the method
-- described in http://en.wikipedia.org/wiki/Companion_matrix
-- This method is for monic polynomials, i.e. with coficient of the
term
-- of greater degree equal to 1, so the input is for the remainder
terms,
-- in descending order e.g. for polynomial
-- x^3 - 2x^2 - x + 2
-- the input is
-- -2 -1 2
with Ada.Command_Line;
with Ada.Numerics.Generic_Real_Arrays;
with Ada.Text_IO;
with Ada.Numerics.Generic_Complex_Types;
with Ada.Numerics.Generic_Complex_Arrays;
procedure Find_Roots_Wikipedia is
type Real is digits 15;
package Real_Arrays is new Ada.Numerics.Generic_Real_Arrays (Real);
package Complex_Types is new Ada.Numerics.Generic_Complex_Types
(Real);
package Complex_Arrays is new Ada.Numerics.Generic_Complex_Arrays
(Real_Arrays, Complex_Types);
N : Natural;
begin
N := Ada.Command_Line.Argument_Count;
declare
C : Complex_Arrays.Complex_Matrix (1 .. N, 1 .. N) := (others =>
(others => (0.0, 0.0)));
-- Using a complex matrix because real matrices for eigenvalues
must be symmetric.
-- Below we convert all real values to complex (with null Im
part).
-- (Still, the complex matrix must be Hamiltonian...)
use Ada.Text_IO;
begin
for I in 1 .. N loop
C (I, N).Re := - Real'Value (Ada.Command_Line.Argument (N - I
+ 1));
if I > 1 then
C (I, I - 1).Re := 1.0;
end if;
end loop;
-- inspect matrix
for i in c'range(1) loop
for j in c'range(2) loop
put (c(i,j).re'img & ", ");
end loop;
new_line;
end loop;
declare
V : Real_Arrays.Real_Vector := Complex_Arrays.Eigenvalues
(C);
use Real_Arrays;
Z : Real;
use Ada.Text_IO;
begin
for I in V'Range loop
Put (Real'Image (V (I)));
Z := V (I) ** N;
for J in 1 .. N loop
Z := Z + C (N, J).Re * V (I) ** (J - 1);
end loop;
Put (" => " & Real'Image (Z));
New_Line;
end loop;
end;
end;
end;
-- Build with:
-- gnatmake find_roots_wikipedia -largs /Developer/SDKs/
MacOSX10.4u.sdk/usr/lib/libblas.dylib /Developer/SDKs/MacOSX10.4u.sdk/
usr/lib/liblapack.dylib
^ permalink raw reply [relevance 7%]
* Re: Incorrect error?
2011-07-18 8:47 6% Incorrect error? ldries46
2011-07-18 9:45 4% ` stefan-lucks
2011-07-18 10:39 6% ` Nicholas Collin Paul de Glouceſter
@ 2011-07-18 15:58 0% ` Adam Beneschan
2 siblings, 0 replies; 200+ results
From: Adam Beneschan @ 2011-07-18 15:58 UTC (permalink / raw)
On Jul 18, 1:47 am, "ldries46" <bertus.dr...@planet.nl> wrote:
> I'm using Ada.Numerics.Generic_Real_Arrays. While Compiling I got the
> following error message:
>
> 65:21 expected type "Ada.Numerics.Generic_Real_Arrays.Real_Vector" from
> instance at line 6
> 65:21 found type "Ada.Numerics.Generic_Real_Arrays.Real_Matrix" from
> instance at line 6
>
> As can be seen Cross, a and b declared as Real_Vector .
> What do I do wrong?
As others have said, you're trying to do something that isn't
defined. There is no "*" operation in Generic_Real_Arrays that takes
two Real_Vector arguments and returns a Real_Vector.
However, I think the error message GNAT is reporting is wrong, and
this should be reported as a GNAT bug. It's no wonder you were
confused. If there were just one function like this:
function Product (Left : Real_Vector; Right : Real_Matrix) return
Real_Vector;
and you tried
Cross := Product (A, B);
GNAT would say "expected type Real_Matrix ... found type Real_Vector",
which is pretty clear. Changing "Product" to "*" and using it as an
operator causes GNAT to generate a different message "there is no
applicable operator". But in the actual package, there are eight
definitions of "*", and the error message GNAT produces doesn't make
sense for any of them, since it's implying that you're actually using
a Real_Matrix as a parameter, when of course you aren't.
-- Adam
> L. Dries
>
> Code:
>
> package Float_Arrays is new Ada.Numerics.Generic_Real_Arrays (float);
> use Float_Arrays;
>
> function Volume (ObjID : integer; Obj : ptrS_Object) return float is
> ok : boolean;
> n : integer := 1;
> Volume : float;
> a : Real_Vector(0 .. 2);
> b : Real_Vector(0 .. 2);
> X0 : Real_Vector(0 .. 2);
> X1 : Real_Vector(0 .. 2);
> X2 : Real_Vector(0 .. 2);
> cross : Real_Vector(0 .. 2);
> nA : Real_Vector(0 .. 2);
> p : ptrNode_Object;
> TempS : ptrS_Object;
> TempT : ptrTriangle_Object;
> begin
> TempS := Obj;
> while n /= ObjID loop
> n := n + 1;
> TempS := TempS.next;
> if TempS = null then
> declare
> NO_NODE_OBJECT : exception;
> begin
> raise NO_NODE_OBJECT;
> end;
> end if;
> end loop;
> n := TempS.PosFaces(0);
> TempT := stT_Object;
> ok := TempT = null;
> while not ok loop
> if TempT.nr = n then
> ok := true;
> else
> TempT := TempT.next;
> ok := TempT = null;
> end if;
> end loop;
> while n < TempS.PosFaces(1) loop
> p := GetPoint(TempT.P1);
> X0(0) := p.pRectangular(x);
> X0(1) := p.pRectangular(y);
> X0(2) := p.pRectangular(z);
> p := GetPoint(TempT.P2);
> X1(0) := p.pRectangular(x);
> X1(1) := p.pRectangular(y);
> X1(2) := p.pRectangular(z);
> p := GetPoint(TempT.P3);
> X2(0) := p.pRectangular(x);
> X2(1) := p.pRectangular(y);
> X2(2) := p.pRectangular(z);
> a := X1 - X0; -- VecSub( a, X1, X0 );
> b := X2 - X0; -- VecSub( b, X2, X0 );
> Cross := a * b; -- VecCross( a, b, Cross );
> <---------------- line 65 the cursor is standing just before *
> nA := Cross * 0.5; -- VecMultScalar( nA, Cross, 0.5 );
> -- Volume = Volume + fabs(VecDot( X0, nA ));
> Volume := Volume + X0(0)*nA(0) + X0(1)*nA(1) + X0(2)*nA(2);
> n := n + 1;
> end loop;
> Volume := Volume/3.0;
> return Volume;
> end Volume;
^ permalink raw reply [relevance 0%]
* Re: Incorrect error?
2011-07-18 10:40 0% ` AdaMagica
2011-07-18 12:39 0% ` Dmitry A. Kazakov
@ 2011-07-18 12:45 4% ` stefan-lucks
1 sibling, 0 replies; 200+ results
From: stefan-lucks @ 2011-07-18 12:45 UTC (permalink / raw)
[-- Attachment #1: Type: TEXT/PLAIN, Size: 2516 bytes --]
On Mon, 18 Jul 2011, AdaMagica wrote:
> Overloading in this way might be seen as unfortunate.
>
> > Ada.Numerics.Generic_Real_Arrays actually provides both:
> >
> > � �function "*" (Left, Right : Real_Vector) return Real'Base;
> > � �function "*" (Left, Right : Real_Vector) return Real_Matrix;
>
> So if you have three vectors, what should A * B * C mean? Even with
> parentheses, it's awkward to read.
I would always prefer to write such an expression with parenthesis. So
look at the expression (A * B) * C, where A, B, and C are vectors.
-> A * B is either a matrix M or a number N.
-> M * C would be a vector.
-> N * C would also be a vector.
===> The result type is a vector.
But wait a minute! There are two different results (either "M * C2 or "N *
C"), and we don't know which is the correct one. So the compiler should
reject this.
The issue is that the result type of "A * B" is different from the types
of A and B. But, as strange as it seems, this is what generations of
Mathematicians and Engineers seem to have found convenient for their work.
I am sure, they where able to understand such expressions from context,
and to provide the context if necessary. Most authors would probably
prefer to write
"M * C with the matrix M being A * B"
instead of "(A * B) * C" with or without "(", ")". They would thus provide
the type information, much like any Ada programmer would (have to) do.
> Now image we have a third function
> function "*" (Left, Right : Real_Vector) return Real_Vector;
>
> BTW: What would such a function return for vectors of less or more
> than 3 dimensions?
It should raise an exception, exactly like
function "+" (Left, Right : Real_Vector) return Real_Vector;
from the Ada.Numerics.Generic_Real_Array package.
I hope the "aspect specifications" from Ada 2012 will allow to specify
that the vector dimensions fit. In an ideal world (or maybe in Ada 2017),
the compiler would then statically reject the program if the vector
dimensions don't fit.
> Why is 'Base the return value? You might instantiate the package with
> a constrained subtype of Float. 'Base is the unconstrained range. Thus
> as long as you stay in the base range, the operators will not
> propagate exceptions.
Ah, that makes sense! Thank you!
--
------ Stefan Lucks -- Bauhaus-University Weimar -- Germany ------
Stefan dot Lucks at uni minus weimar dot de
------ I love the taste of Cryptanalysis in the morning! ------
^ permalink raw reply [relevance 4%]
* Re: Incorrect error?
2011-07-18 10:40 0% ` AdaMagica
@ 2011-07-18 12:39 0% ` Dmitry A. Kazakov
2011-07-18 12:45 4% ` stefan-lucks
1 sibling, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2011-07-18 12:39 UTC (permalink / raw)
On Mon, 18 Jul 2011 03:40:59 -0700 (PDT), AdaMagica wrote:
> Overloading in this way might be seen as unfortunate.
>
>> Ada.Numerics.Generic_Real_Arrays actually provides both:
>>
>> � �function "*" (Left, Right : Real_Vector) return Real'Base;
>> � �function "*" (Left, Right : Real_Vector) return Real_Matrix;
>
> So if you have three vectors, what should A * B * C mean? Even with
> parentheses, it's awkward to read.
There is one or more transpose operation missing, e.g.
A * Transpose (B) * C
Transpose (A) * Transpose (B) * C
Transpose (A) * B * Transpose (C)
etc
> Now image we have a third function
>
> function "*" (Left, Right : Real_Vector) return Real_Vector;
Ah, but vector product has the x-notation. Was introduction of Unicode in
Ada for nothing? (:-))
function "�" (Left, Right : Real_Vector) return Real_Matrix;
> BTW: What would such a function return for vectors of less or more
> than 3 dimensions?
It is also well defined in mathematics, but the problem is same as with
measurement units. The constraints on the matrix dimensions of the
arguments statically determine the constraints of the result matrix
product. One cannot express this in the Ada's type system, otherwise than
by a massive set of overloaded subprograms, which, like for the case of
measurement units, is not a solution. We need some universal mechanism to
describe such cases based on subtypes with static checks of those when the
constraints are static.
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
^ permalink raw reply [relevance 0%]
* Re: Incorrect error?
2011-07-18 9:45 4% ` stefan-lucks
@ 2011-07-18 10:40 0% ` AdaMagica
2011-07-18 12:39 0% ` Dmitry A. Kazakov
2011-07-18 12:45 4% ` stefan-lucks
0 siblings, 2 replies; 200+ results
From: AdaMagica @ 2011-07-18 10:40 UTC (permalink / raw)
Overloading in this way might be seen as unfortunate.
> Ada.Numerics.Generic_Real_Arrays actually provides both:
>
> function "*" (Left, Right : Real_Vector) return Real'Base;
> function "*" (Left, Right : Real_Vector) return Real_Matrix;
So if you have three vectors, what should A * B * C mean? Even with
parentheses, it's awkward to read. Now image we have a third function
function "*" (Left, Right : Real_Vector) return Real_Vector;
BTW: What would such a function return for vectors of less or more
than 3 dimensions?
Why is 'Base the return value? You might instantiate the package with
a constrained subtype of Float. 'Base is the unconstrained range. Thus
as long as you stay in the base range, the operators will not
propagate exceptions.
^ permalink raw reply [relevance 0%]
* Re: Incorrect error?
2011-07-18 8:47 6% Incorrect error? ldries46
2011-07-18 9:45 4% ` stefan-lucks
@ 2011-07-18 10:39 6% ` Nicholas Collin Paul de Glouceſter
2011-07-18 15:58 0% ` Adam Beneschan
2 siblings, 0 replies; 200+ results
From: Nicholas Collin Paul de Glouceſter @ 2011-07-18 10:39 UTC (permalink / raw)
L. Dries <bertus.dries@Planet.NL> sent on July 18th, 2011:
|--------------------------------------------------------------------------------|
|"I'm using Ada.Numerics.Generic_Real_Arrays. While Compiling I got the following|
|error message: |
| |
|65:21 expected type "Ada.Numerics.Generic_Real_Arrays.Real_Vector" from |
|instance at line 6 |
|65:21 found type "Ada.Numerics.Generic_Real_Arrays.Real_Matrix" from |
|instance at line 6 |
| |
|As can be seen Cross, a and b declared as Real_Vector . |
|What do I do wrong? |
| |
|L. Dries |
| |
|[..] |
| a : Real_Vector(0 .. 2); |
| b : Real_Vector(0 .. 2); |
|[..] |
| cross : Real_Vector(0 .. 2); |
|[..] |
| a := X1 - X0; -- VecSub( a, X1, X0 ); |
| b := X2 - X0; -- VecSub( b, X2, X0 ); |
| Cross := a * b; -- VecCross( a, b, Cross ); <---------------- line 65 the |
|cursor is standing just before * |
|[..]" |
|--------------------------------------------------------------------------------|
The product of a 3x1 vector and a 1x3 vector is a 3x3 matrix.
The product of a 3x1 vector and a 3x1 vector can not exist.
You are trying to assign a 2d matrix (that is a * b) to a variable
declared to be a 1d vector.
^ permalink raw reply [relevance 6%]
* Re: Incorrect error?
2011-07-18 8:47 6% Incorrect error? ldries46
@ 2011-07-18 9:45 4% ` stefan-lucks
2011-07-18 10:40 0% ` AdaMagica
2011-07-18 10:39 6% ` Nicholas Collin Paul de Glouceſter
2011-07-18 15:58 0% ` Adam Beneschan
2 siblings, 1 reply; 200+ results
From: stefan-lucks @ 2011-07-18 9:45 UTC (permalink / raw)
On Mon, 18 Jul 2011, ldries46 wrote:
[...]
> a : Real_Vector(0 .. 2);
> b : Real_Vector(0 .. 2);
> cross : Real_Vector(0 .. 2);
> begin
[...]
> Cross := a * b; -- VecCross( a, b, Cross ); <---------------- line 65 the
Why do you expect the product of two vectors to be an vector?
Mathematical convention knows the "inner product" of two vectors (a
single real value) and the "outer product" (a matrix).
Ada.Numerics.Generic_Real_Arrays actually provides both:
function "*" (Left, Right : Real_Vector) return Real'Base;
function "*" (Left, Right : Real_Vector) return Real_Matrix;
So if M is a Real_Matrix(0..2,0..2) and F a float, you can write either
M := a * b; -- outer product
or
F := a * b; -- inner product
but not
Cross := a * b; -- there is no such "*" defined in Ada.Num.Gen_Re_Arr.
Please don't ask me why the inner product is of type "Real'Base", instead
of "Real". I'd like to know that myself. ;-)
BTW, the error messages are not very helpful (at least not until you have
seen many of them and are able to translate them for yourself):
>65:21 expected type "Ada.Numerics.Generic_Real_Arrays.Real_Vector"
> from instance at line 6
>65:21 found type "Ada.Numerics.Generic_Real_Arrays.Real_Matrix" from
> instance at line 6
This really means is that there is no function "*" with two Real_Vector
parameters as the input and returning a Real_Vector in scope.
--
------ Stefan Lucks -- Bauhaus-University Weimar -- Germany ------
Stefan dot Lucks at uni minus weimar dot de
------ I love the taste of Cryptanalysis in the morning! ------
^ permalink raw reply [relevance 4%]
* Incorrect error?
@ 2011-07-18 8:47 6% ldries46
2011-07-18 9:45 4% ` stefan-lucks
` (2 more replies)
0 siblings, 3 replies; 200+ results
From: ldries46 @ 2011-07-18 8:47 UTC (permalink / raw)
I'm using Ada.Numerics.Generic_Real_Arrays. While Compiling I got the
following error message:
65:21 expected type "Ada.Numerics.Generic_Real_Arrays.Real_Vector" from
instance at line 6
65:21 found type "Ada.Numerics.Generic_Real_Arrays.Real_Matrix" from
instance at line 6
As can be seen Cross, a and b declared as Real_Vector .
What do I do wrong?
L. Dries
Code:
package Float_Arrays is new Ada.Numerics.Generic_Real_Arrays (float);
use Float_Arrays;
function Volume (ObjID : integer; Obj : ptrS_Object) return float is
ok : boolean;
n : integer := 1;
Volume : float;
a : Real_Vector(0 .. 2);
b : Real_Vector(0 .. 2);
X0 : Real_Vector(0 .. 2);
X1 : Real_Vector(0 .. 2);
X2 : Real_Vector(0 .. 2);
cross : Real_Vector(0 .. 2);
nA : Real_Vector(0 .. 2);
p : ptrNode_Object;
TempS : ptrS_Object;
TempT : ptrTriangle_Object;
begin
TempS := Obj;
while n /= ObjID loop
n := n + 1;
TempS := TempS.next;
if TempS = null then
declare
NO_NODE_OBJECT : exception;
begin
raise NO_NODE_OBJECT;
end;
end if;
end loop;
n := TempS.PosFaces(0);
TempT := stT_Object;
ok := TempT = null;
while not ok loop
if TempT.nr = n then
ok := true;
else
TempT := TempT.next;
ok := TempT = null;
end if;
end loop;
while n < TempS.PosFaces(1) loop
p := GetPoint(TempT.P1);
X0(0) := p.pRectangular(x);
X0(1) := p.pRectangular(y);
X0(2) := p.pRectangular(z);
p := GetPoint(TempT.P2);
X1(0) := p.pRectangular(x);
X1(1) := p.pRectangular(y);
X1(2) := p.pRectangular(z);
p := GetPoint(TempT.P3);
X2(0) := p.pRectangular(x);
X2(1) := p.pRectangular(y);
X2(2) := p.pRectangular(z);
a := X1 - X0; -- VecSub( a, X1, X0 );
b := X2 - X0; -- VecSub( b, X2, X0 );
Cross := a * b; -- VecCross( a, b, Cross );
<---------------- line 65 the cursor is standing just before *
nA := Cross * 0.5; -- VecMultScalar( nA, Cross, 0.5 );
-- Volume = Volume + fabs(VecDot( X0, nA ));
Volume := Volume + X0(0)*nA(0) + X0(1)*nA(1) + X0(2)*nA(2);
n := n + 1;
end loop;
Volume := Volume/3.0;
return Volume;
end Volume;
^ permalink raw reply [relevance 6%]
* Re: I need feedback
2011-06-16 4:24 5% ` juanmiuk
@ 2011-06-16 7:34 0% ` Ludovic Brenta
0 siblings, 0 replies; 200+ results
From: Ludovic Brenta @ 2011-06-16 7:34 UTC (permalink / raw)
juanmiuk wrote:
> Well, Thank you for all suggestion, I think I follow all of them.
> There you go the final version:
>
> with Ada.Text_IO;
> with Ada.Integer_Text_IO;
> with Ada.Numerics.Discrete_Random;
> with Ada.Strings.Fixed;
>
> use Ada;
> use Ada.Strings.Fixed;
>
> procedure Sort_3_Numbers is
>
> subtype One_Ten is Integer range 1 .. 10;
>
> package Roulette10 is new Ada.Numerics.Discrete_Random(One_Ten);
>
> Gen10: Roulette10.Generator;
>
> WIDTH_NUM : constant One_Ten := One_Ten'Width;
> THE_BASE : constant One_Ten := 10;
This is not necessary, see why below.
> procedure Output_Num
> ( The_Number : in One_Ten;
> Width_Num : in One_Ten;
> The_Base : in One_Ten )
> is
>
> begin
>
> Integer_Text_IO.Put(The_Number, Width_Num, The_Base);
>
> end Output_Num;
This entire procedure does nothing but call Integer_Text_IO.Put, so is
not necessary; you might as well call Integer_Text_IO.Put directly.
In the spec of Integer_Text_IO.Put, the parameter Base has a default
value of 10, so you need not specify it. You could even do away with
Width_Num like this:
package One_Ten_IO is new Ada.Text_IO.Integer_IO (Num => One_Ten);
This would initialize the constant One_Ten_IO.Default_Width to be
One_Ten'Width; you would not have to do it yourself.
> begin
> Roulette10.Reset(Gen10);
> for I in One_Ten'Range loop
> Main_Process : declare
> A : One_Ten := Roulette10.Random(Gen10);
> B : One_Ten := Roulette10.Random(Gen10);
> C : One_Ten := Roulette10.Random(Gen10);
>
> First : One_Ten;
> Secon : One_Ten;
> Third : One_Ten;
> begin
> Output_Num(A, WIDTH_NUM, THE_BASE);
> -- Changing all the Output_Num by Integer_Text_IO.Put(A, WIDTH_NUM, THE_BASE)
> -- as Jeffrey Carter comments then won't be any dupplications.
Or, even more succinctly:
One_Ten_IO.Put (A);
[rest snipped].
Hope this helps.
--
Ludovic Brenta.
^ permalink raw reply [relevance 0%]
* Re: I need feedback
@ 2011-06-16 4:24 5% ` juanmiuk
2011-06-16 7:34 0% ` Ludovic Brenta
0 siblings, 1 reply; 200+ results
From: juanmiuk @ 2011-06-16 4:24 UTC (permalink / raw)
Well, Thank you for all suggestion, I think I follow all of them.
There you go the final version:
with Ada.Text_IO;
with Ada.Integer_Text_IO;
with Ada.Numerics.Discrete_Random;
with Ada.Strings.Fixed;
use Ada;
use Ada.Strings.Fixed;
procedure Sort_3_Numbers is
subtype One_Ten is Integer range 1 .. 10;
package Roulette10 is new Ada.Numerics.Discrete_Random(One_Ten);
Gen10: Roulette10.Generator;
WIDTH_NUM : constant One_Ten := One_Ten'Width;
THE_BASE : constant One_Ten := 10;
procedure Output_Num
( The_Number : in One_Ten;
Width_Num : in One_Ten;
The_Base : in One_Ten )
is
begin
Integer_Text_IO.Put(The_Number, Width_Num, The_Base);
end Output_Num;
begin
Roulette10.Reset(Gen10);
for I in One_Ten'Range loop
Main_Process : declare
A : One_Ten := Roulette10.Random(Gen10);
B : One_Ten := Roulette10.Random(Gen10);
C : One_Ten := Roulette10.Random(Gen10);
First : One_Ten;
Secon : One_Ten;
Third : One_Ten;
begin
Output_Num(A, WIDTH_NUM, THE_BASE);
-- Changing all the Output_Num by Integer_Text_IO.Put(A,
WIDTH_NUM, THE_BASE)
-- as Jeffrey Carter comments then won't be any
dupplications.
Text_IO.Put(", ");
Output_Num(B, WIDTH_NUM, THE_BASE);
Text_IO.Put(", ");
Output_Num(C, WIDTH_NUM, THE_BASE);
Text_IO.Put(" --");
if (A >= B) then
if (A >= C) then
First := A;
if (B >= C) then
-- First := A;
Secon := B;
Third := C;
else
-- First := A;
Secon := C;
Third := B;
end if;
else -- C > A >= B
First := C;
Secon := A;
Third := B;
end if;
elsif (B >= A) then
if (B >= C) then
First := B;
if (A >= C) then
-- First := B;
Secon := A;
Third := C;
else
-- First := B;
Secon := C;
Third := A;
end if;
else -- C > B >= A
First := C;
Secon := B;
Third := A;
end if;
end if;
Output_Num (First, WIDTH_NUM, THE_BASE);
Text_IO.Put(", ");
Output_Num (Secon, WIDTH_NUM, THE_BASE);
Text_IO.Put(", ");
Output_Num (Third, One_Ten'Width, 10);
Text_IO.New_Line;
end Main_Process;
end loop;
end Sort_3_Numbers;
^ permalink raw reply [relevance 5%]
* I need feedback
@ 2011-06-14 21:12 5% juanmiuk
0 siblings, 1 reply; 200+ results
From: juanmiuk @ 2011-06-14 21:12 UTC (permalink / raw)
My name is Juan Miguel and I have ADHD. Since I have long wanted to
learn Ada but I could not learn, because the medication was not
correct and I could not concentrate properly. I returned to writing
simple programs to get base. All I want is to tell me how I am doing.
Thanks in advance.
with Ada.Text_IO;
with Ada.Numerics.Discrete_Random;
with Ada.Strings.Fixed;
use Ada;
use Ada.Strings.Fixed;
procedure ordenar_3_numeros_better is
type UnoDiez is range 1 .. 10;
package Ruleta10 is new Ada.Numerics.Discrete_Random(UnoDiez);
Gen10: Ruleta10.Generator;
begin
Ruleta10.Reset(Gen10);
for I in 1 .. 10 loop
Proceso_Principal: declare
A : UnoDiez := Ruleta10.Random(Gen10);
B : UnoDiez := Ruleta10.Random(Gen10);
C : UnoDiez := Ruleta10.Random(Gen10);
First : UnoDiez;
Secon : UnoDiez;
Third : UnoDiez;
begin
Formateo_Salida_1: declare
Separador1 : String := (UnoDiez'Width - UnoDiez'Image(A)'Length) *
' ';
Separador2 : String := (UnoDiez'Width - UnoDiez'Image(B)'Length) *
' ';
Separador3 : String := (UnoDiez'Width - UnoDiez'Image(C)'Length) *
' ';
begin
Text_IO.Put (
Separador1 & UnoDiez'Image(A) & "," &
Separador2 & UnoDiez'Image(B) & "," &
Separador3 & UnoDiez'Image(C) & " --"
);
end Formateo_Salida_1;
if (A >= B) then
if (A >= C) then
First := A;
if (B >= C) then
-- First := A;
Secon := B;
Third := C;
else
-- First := A;
Secon := C;
Third := B;
end if;
else -- C > A >= B
First := C;
Secon := A;
Third := B;
end if;
elsif (B >= A) then
if (B >= C) then
First := B;
if (A >= C) then
-- First := B;
Secon := A;
Third := C;
else
-- First := B;
Secon := C;
Third := A;
end if;
else -- C > B >= A
First := C;
Secon := B;
Third := A;
end if;
end if;
Formateo_Salida_2: declare
Separador1 : String := (UnoDiez'Width -
UnoDiez'Image(First)'Length) * ' ';
Separador2 : String := (UnoDiez'Width -
UnoDiez'Image(Secon)'Length) * ' ';
Separador3 : String := (UnoDiez'Width -
UnoDiez'Image(Third)'Length) * ' ';
begin
Text_IO.Put (
Separador1 & UnoDiez'Image(First) & "," &
Separador2 & UnoDiez'Image(Secon) & "," &
Separador3 & UnoDiez'Image(Third)
);
Text_IO.New_Line;
end Formateo_Salida_2;
end Proceso_Principal;
end loop;
end ordenar_3_numeros_better;
^ permalink raw reply [relevance 5%]
* Re: Interfacing Ada multidimensional arrays with Fortran.
@ 2011-06-09 7:55 5% ` David Sauvage
0 siblings, 0 replies; 200+ results
From: David Sauvage @ 2011-06-09 7:55 UTC (permalink / raw)
On May 28, 8:45 pm, Simon Wright <si...@pushface.org> wrote:
...
> -O1:
> Transposition: 1200 us
> Assignment: 300 us
>
> -O2:
> Transposition: 500 us
> Assignment: 300 us
Using this testcase [1], here are my results using Intel Atom CPU N270
@ 1.60GHz / Linux (launched with root privilege) :
-O1:
Transposition: 2202 us
Assignment: 1014 us
-O2:
Transposition: 2556 us
Assignment: 885 us
Transposition (using assignment via pragma Convention) seems to be
quicker than Transposition (without pragma Convention).
The reason why pragma Convention (Fortran, Type) is not used in
Interfaces.Fortran... is unknown and seems to give slower compute
time.
[1]
-- gnatmake -f compare.adb -cargs -gnat05 -O2
-- gnatmake -f compare.adb -cargs -gnat05 -O1
with Interfaces.Fortran.BLAS;
with Ada.Text_IO,
Ada.Calendar,
Ada.Numerics.Generic_Real_Arrays;
procedure Compare is
Start, Stop : Ada.Calendar.Time;
use type Ada.Calendar.Time;
type Real_Matrix is
array (Integer range <>, Integer range <>) of
Interfaces.Fortran.Real;
pragma Convention (Fortran, Real_Matrix);
package GRA is new Ada.Numerics.Generic_Real_Arrays (
Interfaces.Fortran.Real);
Row, Column : constant Positive := 100;
Iteration : constant Positive := 10;
M : Real_Matrix (1 .. Row, 1 .. Column) := (others => (others
=> 2.0));
pragma Volatile (M);
MFA, MFB : GRA.Real_Matrix (1 .. Row, 1 .. Column) := (others =>
(others => 2.0));
pragma Volatile (MFA);
pragma Volatile (MFB);
use type Interfaces.Fortran.Real;
begin
Start := Ada.Calendar.Clock;
for I in 1 .. Iteration loop
M := Real_Matrix (MFB);
end loop;
Stop := Ada.Calendar.Clock;
Ada.Text_IO.Put_Line
("Assignation (Transposition via pragma Convention)" &
Duration'Image (Stop - Start));
Start := Ada.Calendar.Clock;
for I in 1 .. Iteration loop
MFA := GRA.Transpose (MFB);
end loop;
Stop := Ada.Calendar.Clock;
Ada.Text_IO.Put_Line
("Transposition" & Duration'Image (Stop - Start));
end Compare;
^ permalink raw reply [relevance 5%]
* Re: Interfacing Ada multidimensional arrays with Fortran.
@ 2011-05-28 9:41 6% ` Simon Wright
0 siblings, 1 reply; 200+ results
From: Simon Wright @ 2011-05-28 9:41 UTC (permalink / raw)
David Sauvage <sauvage.david@gmail.com> writes:
> Concerning multidimensional arrays, Ada use row-major order [0] while
> Fortran use column-major order [1].
> 3 - Concerning BLAS & LAPACK routines, there are parameters to
> indicates the form of the array (transposed or not) to the Fortran
> code, so that the Fortran code load the array properly.
This is true of BLAS, but I don't believe it's true of LAPACK.
> In Interfaces.Fortran.BLAS, there are Multidimensional arrays types
> that are already defined ;
> (Real_Matrix, Double_Precision_Matrix, Complex_Matrix,
> Double_Complex_Matrix)
> But the corresponding pragma Convention (Fortran, type) are not
> defined for them. So any user that would re-use those types can not
> use pragma Convention, and use possibility 2 or 3 above,
Interfaces.Fortran.BLAS is an internal GNAT unit, ie part of GNAT's
implementation of the standard Ada.Numerics.Generic_*_Arrays, not part
of the standard itself.
> It would be interesting to know the story behind the scene of why
> array types declared in Interfaces.Fortran.BLAS do not use pragma
> Convention (Fortran, *) ?
There I can't help you.
The implementor of Ada.Numerics.Generic_Real_Arrays has decided to
declare Interfaces.Fortran.BLAS using Ada order, so that to convert from
the Ada order required in the standard for these units he uses the
Transpose operation (note, a copy is required anyway because LAPACK
doesn't preserve the input matrix).
Functionally, he could equally well have declared in Fortran order, as
you suggest:
with Ada.Text_IO; use Ada.Text_IO;
with Interfaces.Fortran.BLAS;
procedure Sauvage is
type Real_Matrix is array (Integer range <>, Integer range <>)
of Interfaces.Fortran.Real;
pragma Convention (Fortran, Real_Matrix);
Theirs : constant Interfaces.Fortran.BLAS.Real_Matrix :=
(1 => (1 => 1.0, 2 => 2.0),
2 => (1 => 3.0, 2 => 4.0));
Mine : Real_Matrix (1 .. 2, 1 .. 2);
begin
Mine := Real_Matrix (Theirs); -- transposition occurs here
for J in Mine'Range (1) loop
for K in Mine'Range (2) loop
Put_Line (Mine (J, K)'Img);
end loop;
end loop;
end Sauvage;
and it might have been quicker.
Quite how the implementor of Ada.Numerics.Generic_Complex_Arrays managed
the transposition is less than clear to me!
> What are the performance issues by using the three possibilities
> above ? (may be the community already had some interesting information
> about this)
I haven't measured this. Anyone else?
> Some would think the pragma Convention (Fortran, type) should be more
> efficient, but may be it is not that simple, as apparently the choice
> has been made to avoid [4] pragma Convention (Fortran, type).
^ permalink raw reply [relevance 6%]
* Re: Newbie question: Binary operator expected?
2011-05-13 16:05 4% Newbie question: Binary operator expected? Geoffrey Laval
@ 2011-05-13 17:14 0% ` Adam Beneschan
0 siblings, 0 replies; 200+ results
From: Adam Beneschan @ 2011-05-13 17:14 UTC (permalink / raw)
On May 13, 9:05 am, Geoffrey Laval <geolava1...@gmail.com> wrote:
> Hi everybody,
> I'm fairly new to Ada and I've tried different ways, even switching
> from Bounded_Strings to standard strings, I don't know what I do
> wrong!
>
> eightball.adb:8:60: binary operator expected
>
> Here is my source code:
>
> 5 procedure eightball is
> 6 rep : integer range 1 .. 3;
> 7 touche : character;
> 8 package BS_Length is new
> Generic_Bounded_Length(300'Length);
> 9 use BS_Length;
> 10 question : bounded_string;
> 11 question : To_Bounded_String;
> 12 subtype reponse is integer range 1 .. 3;
> 13 package reponseAlea is new
> Ada.Numerics.Discrete_Random(reponse);
> 14 use reponseAlea;
> 15 G : Generator;
> 16 begin
>
> I've changed it several times, and the error is still around the
> length attribute. I think in the course of changing it, I even
> worsened the wrongness of the code. I'm also confused as I've stumbled
> upon different websites and everybody seems to have its own manner to
> use strings. Some use these like I did and others do Sname :
> bounded_string := "something"; so what is the right way?
> I've tried to find out where I was wrong by searching about binary
> operators, but it didn't worked out, so I thought I'd progress easier
> on this if I asked here even if most questions asked are one level or
> a thousand higher than mine. Also, the compiler I'm using is Gnat.
> (Gnat is the compiler, right, and GPS the IDE?)
> Thanks in advance,
> Geoffrey Laval.
300'Length is not Ada syntax. 'Length is an attribute that you can
apply to an *array* or an *array type* to get its length. If A is a
one-dimensional array, A'Length is its length. But 300 isn't an
array, it's a number. If you want to specify *that* the length of
something is 300, this isn't the right syntax for that.
Generic_Bounded_Length(Max => 300) or just Generic_Bounded_Length(300)
will work.
If, on the other hand, you wanted to indicate the length of the
*movie* 300, the Ada language can't be expected to know that. (It's
117 minutes. I looked it up.)
-- Adam
^ permalink raw reply [relevance 0%]
* Newbie question: Binary operator expected?
@ 2011-05-13 16:05 4% Geoffrey Laval
2011-05-13 17:14 0% ` Adam Beneschan
0 siblings, 1 reply; 200+ results
From: Geoffrey Laval @ 2011-05-13 16:05 UTC (permalink / raw)
Hi everybody,
I'm fairly new to Ada and I've tried different ways, even switching
from Bounded_Strings to standard strings, I don't know what I do
wrong!
eightball.adb:8:60: binary operator expected
Here is my source code:
5 procedure eightball is
6 rep : integer range 1 .. 3;
7 touche : character;
8 package BS_Length is new
Generic_Bounded_Length(300'Length);
9 use BS_Length;
10 question : bounded_string;
11 question : To_Bounded_String;
12 subtype reponse is integer range 1 .. 3;
13 package reponseAlea is new
Ada.Numerics.Discrete_Random(reponse);
14 use reponseAlea;
15 G : Generator;
16 begin
I've changed it several times, and the error is still around the
length attribute. I think in the course of changing it, I even
worsened the wrongness of the code. I'm also confused as I've stumbled
upon different websites and everybody seems to have its own manner to
use strings. Some use these like I did and others do Sname :
bounded_string := "something"; so what is the right way?
I've tried to find out where I was wrong by searching about binary
operators, but it didn't worked out, so I thought I'd progress easier
on this if I asked here even if most questions asked are one level or
a thousand higher than mine. Also, the compiler I'm using is Gnat.
(Gnat is the compiler, right, and GPS the IDE?)
Thanks in advance,
Geoffrey Laval.
^ permalink raw reply [relevance 4%]
* Re: on using array index, vectorized operation
2011-03-29 2:50 6% ` Randy Brukardt
@ 2011-03-29 4:55 0% ` Nasser M. Abbasi
0 siblings, 0 replies; 200+ results
From: Nasser M. Abbasi @ 2011-03-29 4:55 UTC (permalink / raw)
On 3/28/2011 7:50 PM, Randy Brukardt wrote:
> "Nasser M. Abbasi"<nma@12000.org> wrote in message
>> Does not look like it either, not directly any way:
>>
>> ---------------------
>> procedure foo2 is
>>
>> type array_t is array(natural range<>) of integer;
>> u : array_t(1..10) := (others=>0);
>>
>> begin
>> u := u + 1;
>> end foo2;
>
> You can do this for float values by using Generic_Real_Arrays:
>
> with Ada.Numerics.Generic_Real_Arrays;
> procedure foo3 is
>
> package My_Vectors is new Ada.Numerics.Generic_Real_Arrays (Float);
> use My_Vectors;
>
> subtype array_t is Real_Vector;
>
> u : array_t(1..10) := (others=>0.0);
>
> begin
> u := u + (others => 1.0);
> u := u * 1.0;
> end foo3;
>
> I'd suggest writing your own package similar to Generic Real_Arrays to
> define your own vector types, complete with overloaded operators. You only
> have to do that once, and the uses can be much simpler in your code. That's
> a much better option than writing loads of loops in your code that ruin the
> readability.
>
> Just because something isn't provided for free with Ada doesn't mean that
> you can't write a similar replacement...
>
> Randy.
>
>
Thanks Randy ! That really helped. I am a newbie at Ada and did
not know about such package. (but strange it is only for float?
But I suppose one can duplicate it for other types).
I rewrote the procedure using this package (I am using float, so
it worked for me), and was really surprised that now I able
to remove the loop and use vectorized statement:
-------------
subtype r is Natural range o.u'First + 1 .. o.u'Last - 1;
subtype r_plus_1 is Natural range r'First + 1 .. r'Last + 1;
subtype r_minus_1 is Integer range r'First - 1 .. r'Last - 1;
begin
u (r) := u (r) -
(a / 2.0) * (u (r_plus_1) - u (r_minus_1)) +
(a ** 2) / 2.0 *
(u (r_minus_1) - 2.0 * u (r) + u(r_plus_1));
-------------
It is now almost the same form as in Fortran and Matlab !
Only extra thing is the need to define those subtype's for
the ranges. (r, r_plus_1, r_minus_1) .
In Fortran, I would have written the above as
-----------------------------------------
u (i) := u (i) -
(a / 2.0) * (u (i+1) - u (i-1)) +
(a ** 2) / 2.0 *
(u (i-1) - 2.0 * u (i) + u(i+1) )
----------------------------------------------
Where 'i' is an array of the index range I am interested in.
It would be great if there is another 'trick' to allow
me to write it as such in Ada. I am still not too happy
with having to do this, but this is a very minor thing now
for me and I can life with it.
Removing the loop is a major improvement from what I started
with. I like Ada now again :) since I am able to write
the code in a much close form as I am used to.
Fyi, I've updated my small Ada Lax-Wendroff package here which
I used to practice on.
http://12000.org/my_notes/solve_advection_1D_in_Ada/index.htm
thanks again for all who helped.
--Nasser
^ permalink raw reply [relevance 0%]
* Re: on using array index, vectorized operation
@ 2011-03-29 2:50 6% ` Randy Brukardt
2011-03-29 4:55 0% ` Nasser M. Abbasi
0 siblings, 1 reply; 200+ results
From: Randy Brukardt @ 2011-03-29 2:50 UTC (permalink / raw)
"Nasser M. Abbasi" <nma@12000.org> wrote in message
news:imodcl$4sk$1@speranza.aioe.org...
> On 3/27/2011 3:09 PM, Phil Clayton wrote:
>> Do we now have vectorized arithmetic operations, e.g. + on array
>> types?
Not on all array types, but the Generic_Real_Arrays provides vector and
matrix operations. Unfortunately, only for float values.
> Does not look like it either, not directly any way:
>
> ---------------------
> procedure foo2 is
>
> type array_t is array(natural range <>) of integer;
> u : array_t(1..10) := (others=>0);
>
> begin
> u := u + 1;
> end foo2;
You can do this for float values by using Generic_Real_Arrays:
with Ada.Numerics.Generic_Real_Arrays;
procedure foo3 is
package My_Vectors is new Ada.Numerics.Generic_Real_Arrays (Float);
use My_Vectors;
subtype array_t is Real_Vector;
u : array_t(1..10) := (others=>0.0);
begin
u := u + (others => 1.0);
u := u * 1.0;
end foo3;
I'd suggest writing your own package similar to Generic Real_Arrays to
define your own vector types, complete with overloaded operators. You only
have to do that once, and the uses can be much simpler in your code. That's
a much better option than writing loads of loops in your code that ruin the
readability.
Just because something isn't provided for free with Ada doesn't mean that
you can't write a similar replacement...
Randy.
^ permalink raw reply [relevance 6%]
* Re: Help with low level Ada
2011-03-17 17:55 4% ` Jeffrey Carter
@ 2011-03-17 19:30 0% ` Syntax Issues
0 siblings, 0 replies; 200+ results
From: Syntax Issues @ 2011-03-17 19:30 UTC (permalink / raw)
On Mar 17, 1:55 pm, Jeffrey Carter
<spam.jrcarter....@spam.not.acm.org> wrote:
> On 03/17/2011 07:31 AM, Syntax Issues wrote:
>
>
>
>
>
>
>
>
>
> > unsigned ColorNormalize (vec3_t rgb){
> > unsigned c;
> > float max;
> > ...
> > ((byte *)&c)[0] = rgb[0] * max;
> > ((byte *)&c)[1] = rgb[1] * max;
> > ((byte *)&c)[2] = rgb[2] * max;
> > ((byte *)&c)[3] = 255;
> > return c;
> > }
> > function Normalize
> > (Red_Green_Blue : in Vector_Color)
> > return Integer_Color
> > is
> > Result : Integer_Color := 0;
> > Maximum : Float_4 := 0.0;
> > begin
> > ...
> > return
> > -- ???!!??!?!? Byte(Red_Green_Blue(1) * Maximum) +
> > -- ???!!??!?!? Byte(Red_Green_Blue(2) * Maximum) +
> > -- ???!!??!?!? Byte(Red_Green_Blue(3) * Maximum);
> > end Normalize;
>
> First, I'd probably do something like
>
> type Color_ID is (Red, Blue, Green);
>
> subtype Natural_Float_4 is Float_4 range 0.0 .. Float_4'Last;
>
> type Vector_Color is array (Color_ID) of Natural_Float_4;
>
> so I can say Red_Green_Blue (Red). (I presume that the components of
> Vector_Color cannot be negative; better to make that clear in the code and
> enforced by the language.)
>
> One approach to this is
>
> type Byte is mod 2 ** 8;
>
> type Color_Bytes is record
> Red : Byte;
> Green : Byte;
> Blue : Byte;
> Unused : Byte;
> end record;
> for Color_Bytes use
> Red at 0 range 0 .. 7;
> Green at 1 range 0 .. 7;
> Blue at 2 range 0 .. 7;
> Unused at 3 range 0 .. 7;
> end record;
> for Color_Bytes'Size use Integer_Color'Size;
>
> You may need to change the representation clause to get the components in the
> right places.
>
> function Convert is new Ada.Unchecked_Conversion
> (Source => Color_Bytes, Target => Integer_Color);
>
> Result := Color_Bytes'(Red => Byte (Red_Green_Blue (Red) * Maximum),
> Green => Byte (Red_Green_Blue (Green) * Maximum),
> Blue => Byte (Red_Green_Blue (Blue) * Maximum),
> Unused => Byte'Last);
>
> return Convert (Result);
>
> You missed out the assignment of 255 to the 4th byte.
>
> Another way is to use an array of 4 Bytes that you unchecked convert to the
> result type.
>
> Finally, if you use a modular type from package Interfaces you can shift the
> products into their correct positions and "or" them together. And you can always
> imitate that by multiplying by a power of 2 and adding them together:
>
> Result := Integer_Color (Red_Green_Blue (Red) * Maximum) * 2 ** 0 +
> Integer_Color (Red_Green_Blue (Green) * Maximum) * 2 ** 8 +
> Integer_Color (Red_Green_Blue (Blue) * Maximum) * 2 ** 16 +
> 255 * 2 ** 24;
>
> The compiler will often replace these by shifts.
>
> > float AngleMod (float angle){
> > return (360.0/65536) * ((int)(angle * (65536/360.0))& 65535);
> > }
> > function Mod_Angle
> > (Angle : in Float_4)
> > return Float_4
> > is
> > begin
> > return (360.0 / 65536.0) * (Integer_4_Signed(Angle * (65536.0 /
> > 360.0)) ---???!?!?!& 65535);
> > end Mod_Angle;
>
> Bitwise "and" is defined for all modular types. The only wrinkle is what happens
> if Angle is negative. If that's not allowed (see Natural_Float_4 above), then
> it's fairly easy:
>
> type Integer_4_Unsigned is mod Integer_4_Signed'Size;
>
> return (360.0 / 65536.0) *
> Float_4 (Integer_4_Unsigned (Angle * (65536.0 / 360.0) ) and 65535);
>
> Otherwise, you need to do some unchecked converting between signed and modular
> types of the same size:
>
> function Convert is new Ada.Unchecked_Conversion
> (Source => Integer_4_Signed, Target => Integer_4_Unsigned);
>
> return (360.0 / 65536.0) *
> Float_4 (Convert (Integer_4_Signed (Angle * (65536.0 / 360.0) ) ) and
> 65535);
>
> (I presume that Integer_4_Signed is 4 bytes from its name, so the result of
> "and"ing that with 65535 will always be non-negative. In that case, there's no
> need to convert back to signed before converting to Float_4.)
>
> > int NearestPowerOfTwo (int number, qboolean roundDown){
> > int n = 1;
> > if (number<= 0)
> > return 1;
> > while (n< number)
> > n<<= 1;
> > if (roundDown){
> > if (n> number)
> > n>>= 1;
> > }
> > return n;
> > }
>
> Shift operations are defined for the modular types defined in package
> Interfaces. As mentioned above, the same effect can often be obtained with
> multiplication and division by powers of 2, and the compiler will often replace
> them with shifts:
>
> while N < Number loop
> N := 2 * N;
> end loop;
>
> if Round_Down and N > Number then
> N := N / 2;
> end if;
>
> You could also use the Log function from Ada.Numerics.Generic_Elementary_Functions:
>
> type Big is digits 15;
>
> package Math is new Ada.Numerics.Generic_Elementary_Functions
> (Float_Type => Big);
>
> N := 2 ** Integer (Math.Log (Big (Number), 2.0) );
>
> if N < Number then
> N := 2 * N;
> end if;
>
> if Round_Down and N > Number then
> N := N / 2;
> end if;
>
> --
> Jeff Carter
> "We use a large, vibrating egg."
> Annie Hall
> 44
Excellent, I really appreciate the help.
^ permalink raw reply [relevance 0%]
* Re: Help with low level Ada
@ 2011-03-17 17:55 4% ` Jeffrey Carter
2011-03-17 19:30 0% ` Syntax Issues
0 siblings, 1 reply; 200+ results
From: Jeffrey Carter @ 2011-03-17 17:55 UTC (permalink / raw)
On 03/17/2011 07:31 AM, Syntax Issues wrote:
> unsigned ColorNormalize (vec3_t rgb){
> unsigned c;
> float max;
> ...
> ((byte *)&c)[0] = rgb[0] * max;
> ((byte *)&c)[1] = rgb[1] * max;
> ((byte *)&c)[2] = rgb[2] * max;
> ((byte *)&c)[3] = 255;
> return c;
> }
> function Normalize
> (Red_Green_Blue : in Vector_Color)
> return Integer_Color
> is
> Result : Integer_Color := 0;
> Maximum : Float_4 := 0.0;
> begin
> ...
> return
> -- ???!!??!?!? Byte(Red_Green_Blue(1) * Maximum) +
> -- ???!!??!?!? Byte(Red_Green_Blue(2) * Maximum) +
> -- ???!!??!?!? Byte(Red_Green_Blue(3) * Maximum);
> end Normalize;
First, I'd probably do something like
type Color_ID is (Red, Blue, Green);
subtype Natural_Float_4 is Float_4 range 0.0 .. Float_4'Last;
type Vector_Color is array (Color_ID) of Natural_Float_4;
so I can say Red_Green_Blue (Red). (I presume that the components of
Vector_Color cannot be negative; better to make that clear in the code and
enforced by the language.)
One approach to this is
type Byte is mod 2 ** 8;
type Color_Bytes is record
Red : Byte;
Green : Byte;
Blue : Byte;
Unused : Byte;
end record;
for Color_Bytes use
Red at 0 range 0 .. 7;
Green at 1 range 0 .. 7;
Blue at 2 range 0 .. 7;
Unused at 3 range 0 .. 7;
end record;
for Color_Bytes'Size use Integer_Color'Size;
You may need to change the representation clause to get the components in the
right places.
function Convert is new Ada.Unchecked_Conversion
(Source => Color_Bytes, Target => Integer_Color);
Result := Color_Bytes'(Red => Byte (Red_Green_Blue (Red) * Maximum),
Green => Byte (Red_Green_Blue (Green) * Maximum),
Blue => Byte (Red_Green_Blue (Blue) * Maximum),
Unused => Byte'Last);
return Convert (Result);
You missed out the assignment of 255 to the 4th byte.
Another way is to use an array of 4 Bytes that you unchecked convert to the
result type.
Finally, if you use a modular type from package Interfaces you can shift the
products into their correct positions and "or" them together. And you can always
imitate that by multiplying by a power of 2 and adding them together:
Result := Integer_Color (Red_Green_Blue (Red) * Maximum) * 2 ** 0 +
Integer_Color (Red_Green_Blue (Green) * Maximum) * 2 ** 8 +
Integer_Color (Red_Green_Blue (Blue) * Maximum) * 2 ** 16 +
255 * 2 ** 24;
The compiler will often replace these by shifts.
> float AngleMod (float angle){
> return (360.0/65536) * ((int)(angle * (65536/360.0))& 65535);
> }
> function Mod_Angle
> (Angle : in Float_4)
> return Float_4
> is
> begin
> return (360.0 / 65536.0) * (Integer_4_Signed(Angle * (65536.0 /
> 360.0)) ---???!?!?!& 65535);
> end Mod_Angle;
Bitwise "and" is defined for all modular types. The only wrinkle is what happens
if Angle is negative. If that's not allowed (see Natural_Float_4 above), then
it's fairly easy:
type Integer_4_Unsigned is mod Integer_4_Signed'Size;
return (360.0 / 65536.0) *
Float_4 (Integer_4_Unsigned (Angle * (65536.0 / 360.0) ) and 65535);
Otherwise, you need to do some unchecked converting between signed and modular
types of the same size:
function Convert is new Ada.Unchecked_Conversion
(Source => Integer_4_Signed, Target => Integer_4_Unsigned);
return (360.0 / 65536.0) *
Float_4 (Convert (Integer_4_Signed (Angle * (65536.0 / 360.0) ) ) and
65535);
(I presume that Integer_4_Signed is 4 bytes from its name, so the result of
"and"ing that with 65535 will always be non-negative. In that case, there's no
need to convert back to signed before converting to Float_4.)
> int NearestPowerOfTwo (int number, qboolean roundDown){
> int n = 1;
> if (number<= 0)
> return 1;
> while (n< number)
> n<<= 1;
> if (roundDown){
> if (n> number)
> n>>= 1;
> }
> return n;
> }
Shift operations are defined for the modular types defined in package
Interfaces. As mentioned above, the same effect can often be obtained with
multiplication and division by powers of 2, and the compiler will often replace
them with shifts:
while N < Number loop
N := 2 * N;
end loop;
if Round_Down and N > Number then
N := N / 2;
end if;
You could also use the Log function from Ada.Numerics.Generic_Elementary_Functions:
type Big is digits 15;
package Math is new Ada.Numerics.Generic_Elementary_Functions
(Float_Type => Big);
N := 2 ** Integer (Math.Log (Big (Number), 2.0) );
if N < Number then
N := 2 * N;
end if;
if Round_Down and N > Number then
N := N / 2;
end if;
--
Jeff Carter
"We use a large, vibrating egg."
Annie Hall
44
^ permalink raw reply [relevance 4%]
* Error in gnat-4.6 (opensuse 11.4) ?
@ 2011-03-17 13:33 6% reinkor
0 siblings, 0 replies; 200+ results
From: reinkor @ 2011-03-17 13:33 UTC (permalink / raw)
Hello there,
I did strip down my program to the following (below) in order to
communicate
a possible error in gnat-4.6 (I use opensuse 11.4 on an hp Elitebook
6930p).
Could anybody try the same?
I get the following (test1.adb is listed below):
gnatmake -gnat2012 test1.adb
gcc -c -gnat2012 test1.adb
gnatbind -x test1.ali
gnatlink test1.ali
aaa > ./test1
raised STORAGE_ERROR : stack overflow (or erroneous memory access)
If I change: "type Real is Digits 16;" -> "type Real is Digits
15;"
then I do not get "stack overflow". Similarly, if I comment out for
example the statement " fe,xe : fe_t;"
reinert
------------------program listing-----------------
with Text_IO;
use Text_IO;
with Ada.Numerics.Float_Random;
use Ada.Numerics.Float_Random;
use Ada.Numerics;
procedure test1 is
type Real is Digits 16;
G : Float_Random.Generator;
type f_t is array(1..0400) of Real;
type fe_t is array(1..1000) of Real;
type Node_t is
record
f, fm : f_t;
fe,xe : fe_t;
x : Real;
end record;
Node : array (1..200) of Node_t;
procedure initiate_nodes is
begin
for i in Node'range loop
Node(i).x := Real(Float_Random.Random(Gen => G));
end loop;
end initiate_nodes;
begin
Put( " Hello World! ");
end test1;
^ permalink raw reply [relevance 6%]
* Re: Need some light on using Ada or not
@ 2011-02-22 2:15 3% ` Shark8
0 siblings, 0 replies; 200+ results
From: Shark8 @ 2011-02-22 2:15 UTC (permalink / raw)
On Feb 21, 4:52 am, Brian Drummond <brian_drumm...@btconnect.com>
wrote:
>
> As this is my first experiment with tasking, comments are welcome (and I'd be
> interested to see your version). If people think this is worth submitting to the
> shootout, I'll go ahead.
>
> - Brian
I used arrays for the most part, and then expanded it out to a
recursive-definition for the trees which would be too large for
the stack during creation.
It may be going against the spirit of the competition, but nothing
there said that we couldn't use arrays as binary-trees.
-- Package B_Tree
-- by Joey Fish
Package B_Tree is
-- Contest rules state:
-- define a tree node class and methods, a tree node record and
procedures,
-- or an algebraic data type and functions.
--
-- B_Tree is the definition of such a record and procedures.
Type Binary_Tree is Private;
Function Build_Tree (Item : Integer; Depth : Natural) Return
Binary_Tree;
Function Subtree (Tree : Binary_Tree; Left : Boolean) Return
Binary_Tree;
Function Item_Check (This : Binary_Tree) Return Integer;
Procedure Free (Tree : In Out Binary_Tree);
Private
Type Node_Data;
Type Data_Access is Access Node_Data;
SubType Not_Null_Data_Access is Not Null Data_Access;
Function Empty Return Not_Null_Data_Access;
Type Binary_Tree( Extension : Boolean:= False ) is Record
Data : Not_Null_Data_Access:= Empty;
End Record;
End B_Tree;
--- B_Trees body
with
Ada.Text_IO,
--Ada.Numerics.Generic_Elementary_Functions,
Unchecked_Deallocation;
Package Body B_Tree is
-- In some cases the allocataion of the array is too large, so we
can split
-- that off into another tree, for that we have Tree_Array, which
is a
-- Boolean-indexed array. {The Index is also shorthand for Is_left
on such.}
Type Tree_Array is Array (Boolean) of Binary_Tree;
-- For trees of up to 2**17 items we store the nodes as a simple
array.
Type Integer_Array is Array (Positive Range <>) of Integer;
Type Access_Integers is Access Integer_Array;
Type Node_Data(Extended : Boolean:= False) is Record
Case Extended is
When False => A : Not Null Access_Integers;
When True => B : Tree_Array;
end Case;
End Record;
-- Returns the Empty List's Data.
Function Empty Return Not_Null_Data_Access is
begin
Return New Node_Data'( A => New Integer_Array'(2..1 => 0),
Others => <> );
end Empty;
-- We'll need an integer-version of logrithm in base-2
Function lg( X : In Positive ) Return Natural is
--------------------------------------------
-- Base-2 Log with a jump-table for the --
-- range 1..2**17-1 and a recursive call --
-- for all values greater. --
--------------------------------------------
begin
Case X Is
When 2**00..2**01-1 => Return 0;
When 2**01..2**02-1 => Return 1;
When 2**02..2**03-1 => Return 2;
When 2**03..2**04-1 => Return 3;
When 2**04..2**05-1 => Return 4;
When 2**05..2**06-1 => Return 5;
When 2**06..2**07-1 => Return 6;
When 2**07..2**08-1 => Return 7;
When 2**08..2**09-1 => Return 8;
When 2**09..2**10-1 => Return 9;
When 2**10..2**11-1 => Return 10;
When 2**11..2**12-1 => Return 11;
When 2**12..2**13-1 => Return 12;
When 2**13..2**14-1 => Return 13;
When 2**14..2**15-1 => Return 14;
When 2**15..2**16-1 => Return 15;
When 2**16..2**17-1 => Return 16;
When Others => Return 16 + lg( X / 2**16 );
End Case;
end lg;
Function Build_Tree (Item : Integer; Depth : Natural) Return
Binary_Tree is
-- Now we need a function to allow the calculation of a node's
value
-- given that node's index.
Function Value( Index : Positive ) Return Integer is
Level : Integer:= lg( Index );
-- Note: That is the same as
-- Integer( Float'Truncation( Log( Float(Index),2.0 ) ) );
-- but without the Integer -> Float & Float -> Integer conversions.
begin
Return (-2**(1+Level)) + 1 + Index;
end;
Begin
If Depth < 17 then
Return Result : Binary_Tree do
Result.Data:= New Node_Data'
( A => New Integer_Array'(1..2**Depth-1 => <>), Others => <> );
For Index in Result.Data.A.All'Range Loop
Result.Data.All.A.All( Index ):= Value(Index) + Item;
End Loop;
End Return;
else
Return Result : Binary_Tree do
Result.Data:= New Node_Data'
( B =>
(True => Build_Tree(-1,Depth-1), False =>
Build_Tree(0,Depth-1)),
Extended => True );
End Return;
end if;
End Build_Tree;
Function Subtree (Tree : Binary_Tree; Left : Boolean) Return
Binary_Tree is
Begin
if Tree.Data.Extended then
-- If it is a large enough tree, then we already have it
split.
Return Tree.Data.B(Left);
else
-- If not then we just need to calculate the middle and
return the
-- proper half [excluding the first (root) node.
Declare
Data : Integer_Array Renames Tree.Data.All.A.All;
Data_Length : Natural:= Data'Length;
Mid_Point : Positive:= (Data_Length/2) + 1;
SubType LeftTree is Positive Range
Positive'Succ(1)..Mid_Point;
SubType RightTree is Positive Range
Positive'Succ(Mid_Point)..Data_Length;
Begin
Return Result : Binary_Tree Do
if Left then
Result.Data:= New Node_Data'
( A => New Integer_Array'( Data(LeftTree) ),
Others => <> );
else
Result.Data:= New Node_Data'
( A => New Integer_Array'( Data(RightTree) ),
Others => <> );
end if;
End Return;
End;
end if;
End Subtree;
Function Check_Sum( Data: In Integer_Array ) Return Integer is
Depth : Natural:= lg(Data'Length);
SubType Internal_Nodes is Positive Range 1..2**Depth-1;
begin
Return Result : Integer:= 0 do
For Index in Internal_Nodes Loop
Declare
Left : Positive:= 2*Index;
Right : Positive:= Left+1;
Begin
If Index mod 2 = 1 then
Result:= Result - Right + Left;
else
Result:= Result + Right - Left;
end if;
End;
End Loop;
End Return;
end Check_Sum;
Function Item_Check (This : Binary_Tree) Return Integer is
-- For large trees this function calls itself recursively until
the
-- smaller format is encountered; otherwise, for small trees, it
acts as
-- a pass-througn to Check_Sum.
Begin
If This.Data.Extended then
Declare
Begin
Return Result: Integer:= -1 do
Result:= Result
+ Item_Check( This.Data.B(False) )
- Item_Check( This.Data.B(True ) );
End Return;
End;
else
Declare
Data : Integer_Array Renames This.Data.All.A.All;
Begin
Return Check_Sum( Data );
End;
end if;
End Item_Check;
Procedure Free (Tree : In Out Binary_Tree) is
procedure Deallocate is new
Unchecked_Deallocation(Integer_Array, Access_Integers);
procedure Deallocate is new
Unchecked_Deallocation(Node_Data, Data_Access);
Procedure Recursive_Free (Tree : In Out Binary_Tree) is
begin
if Tree.Data.All.Extended then
Recursive_Free( Tree.Data.B(True ) );
Recursive_Free( Tree.Data.B(False) );
Declare
Data : Data_Access;
For Data'Address Use Tree.Data'Address;
Pragma Import( Ada, Data );
Begin
Deallocate(Data);
End;
else
Declare
Data : Data_Access;
For Data'Address Use Tree.Data.All.A'Address;
Pragma Import( Ada, Data );
Begin
Deallocate( Data );
Data:= Empty;
End;
end if;
end Recursive_Free;
begin
Recursive_Free( Tree );
Tree.Data:= Empty;
end Free;
Begin
Null;
End B_Tree;
-- BinaryTrees.adb
-- by Jim Rogers
-- modified by Joey Fish
With
B_Tree,
Ada.Text_Io,
Ada.Real_Time,
Ada.Command_Line,
Ada.Characters.Latin_1,
;
Use
B_Tree,
Ada.Text_Io,
Ada.Command_Line,
Ada.Integer_Text_Io,
Ada.Characters.Latin_1
;
procedure BinaryTrees is
--Depths
Min_Depth : Constant Positive := 4;
Max_Depth : Positive;
Stretch_Depth: Positive;
N : Natural := 1;
-- Trees
Stretch_Tree,
Long_Lived_Tree : Binary_Tree;
Check,
Sum : Integer;
Depth : Natural;
Iterations : Positive;
Package Fn is New
Ada.Numerics.Generic_Elementary_Functions( Float );
Function Value( Index : Positive ) Return Integer is
Level : Integer:=
Integer( Float'Truncation( Fn.Log( Float(Index),2.0 ) ) );
begin
Return (-2**(1+Level)) + 1 + Index;
end;
begin
-- For Index in 1..2**3-1 loop
-- Put_Line( Value(Index)'img );
-- end loop;
-- Declare
-- -- allocate new memory:
-- Short_Lived_Tree_1: Binary_Tree:= Build_Tree(0, 20);
-- Begin
-- Sum:= Item_Check (Short_Lived_Tree_1);
-- -- Check := Check + Sum;
-- -- Free( Short_Lived_Tree_1 );
-- Put(Check'Img);
-- End;
if Argument_Count > 0 then
N := Positive'Value(Argument(1));
end if;
Max_Depth := Positive'Max(Min_Depth + 2, N);
Stretch_Depth := Max_Depth + 1;
Stretch_Tree := Build_Tree(0, Stretch_Depth);
Check:= Item_Check(Stretch_Tree);
Put("stretch tree of depth ");
Put(Item => Stretch_Depth, Width => 1);
Put(Ht & " check: ");
Put(Item => Check, Width => 1);
New_Line;
Long_Lived_Tree := Build_Tree(0, Max_Depth);
Depth := Min_Depth;
while Depth <= Max_Depth loop
Iterations := 2**(Max_Depth - Depth + Min_Depth);
Check := 0;
for I in 1..Iterations loop
Declare
Short_Lived_Tree_1: Binary_Tree:= Build_Tree(I, Depth);
Begin
Sum:= Item_Check (Short_Lived_Tree_1);
Check := Check + Sum;
Free( Short_Lived_Tree_1 );
End;
Declare
Short_Lived_Tree_2: Binary_Tree:= Build_Tree(-I, Depth);
Begin
Sum:= Item_Check (Short_Lived_Tree_2);
Check := Check + Sum;
Free( Short_Lived_Tree_2 );
End;
end loop;
Put(Item => Iterations * 2, Width => 0);
Put(Ht & " trees of depth ");
Put(Item => Depth, Width => 0);
Put(Ht & " check: ");
Put(Item => Check, Width => 0);
New_Line;
Depth := Depth + 2;
end loop;
Put("long lived tree of depth ");
Put(Item => Max_Depth, Width => 0);
Put(Ht & " check: ");
check:= Item_Check(Long_Lived_Tree);
Put(Item => Check, Width => 0);
New_Line;
end BinaryTrees;
^ permalink raw reply [relevance 3%]
* Re: Ann: Mathpaqs, release Feb. 2011
@ 2011-02-21 23:59 6% ` Nasser M. Abbasi
0 siblings, 0 replies; 200+ results
From: Nasser M. Abbasi @ 2011-02-21 23:59 UTC (permalink / raw)
On 2/21/2011 10:43 AM, Gautier write-only wrote:
> Hello,
>
> There is a new release of Mathpaqs @ http://sf.net/projects/mathpaqs/
> .
>
> What's new:
>
> - *new* Discrete_random_simulation package (this is for simulating any
> discrete random distribution)
> - updated the Finite_distributed_random function (this is for
> simulating a random distribution for an enumerated type)
> - cleanup of ConjGrad (Conjugate gradient iterative methods for
> solving the matrix equation Ax=b)
>
Thanks Gautier,
I do not use Ada now, but I was looking at your ConjGrad solver,
and was just wondering, why new Matrix and Vectors are
defined in that package, since with Ada now, there exist
such types now?
For example, in ConjGrad.ads it says
type Vector is array(Index range <>) of Real
type Any_matrix (<>) is private;
-- NB: 2 syntaxes for instanciating that as unconstrained type :
-- [Ada 95+] type Any_matrix (<>) is private;
-- [Ada 83] type Any_matrix is private;
But when I look at Ada 2005,
http://www.adaic.org/resources/add_content/standards/05rat/html/Rat-7-6.html
"Ada 2005 includes two new packages which are Ada.Numerics.Generic_Real_Arrays and Ada.Numerics.Generic_Complex_Arrays.
type Real_Vector is array (Integer range <>) of Real'Base;
type Real_Matrix is array (Integer range <>, Integer range <>) of Real'Base;
"
So, was just wondering the reasoning, to learn something, that's all.
I wrote a conjugate gradient solver myself for a HW, with preconditioning
in Matlab, and I saw your post, so wanted to see how it would 'look' in Ada.
thanks
--Nasser
^ permalink raw reply [relevance 6%]
* Re: How do I write directly to a memory address?
2011-02-07 18:10 0% ` Georg Bauhaus
@ 2011-02-07 19:29 0% ` Dmitry A. Kazakov
0 siblings, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2011-02-07 19:29 UTC (permalink / raw)
On Mon, 07 Feb 2011 19:10:12 +0100, Georg Bauhaus wrote:
> On 07.02.11 16:21, Dmitry A. Kazakov wrote:
>
>>> It means that Ada function Ada.Numerics.Discrete_Random.Random
>>> only works because it violates its "contract". The parameter (a
>>> generator object) is passed "in", but is modified. Its mutation
>>> is one effect of calling function Random.
>>
>> Wrong. You might have an implementation of Random backed by the hardware in
>> which case Random would have no internal state whatsoever.
>
> An implementation does not specify the language. By the language,
> Random relies on the fact that whenever it is finished, it will
> deliver the "next" value ("from its generator"). The state of a
> Generator can be saved and restored, so the notion of its state
> is meaningful in the abstract.
That is specific to the procedure Reset, which is not essential for random
number generation.
> Since we are discussion the effects of subprogram specs on programmer
> intuition, Random's parameter Gen being of mode "in" is at odds with
> the usual meaning of "in".
Not at all. It is Reset, which probably is. Random is perfectly OK.
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
^ permalink raw reply [relevance 0%]
* Re: How do I write directly to a memory address?
2011-02-07 16:14 5% ` Robert A Duff
2011-02-07 17:23 0% ` Dmitry A. Kazakov
@ 2011-02-07 18:38 0% ` Jeffrey Carter
1 sibling, 0 replies; 200+ results
From: Jeffrey Carter @ 2011-02-07 18:38 UTC (permalink / raw)
On 02/07/2011 09:14 AM, Robert A Duff wrote:
>
> I don't think a truly random implementation of
> Ada.Numerics. ... .Random would be correct,
> because you're allowed to reset the state to a
> previously-saved state, and replay they exact same sequence
> of pseudo-random numbers.
>
> It might be useful to have a truly-random function, but
> it would have to be a different one.
I suppose you could save the sequence of values returned so far, and the state
would be an index into that sequence.
--
Jeff Carter
"We burst our pimples at you."
Monty Python & the Holy Grail
16
^ permalink raw reply [relevance 0%]
* Re: How do I write directly to a memory address?
2011-02-07 15:21 0% ` Dmitry A. Kazakov
2011-02-07 16:14 5% ` Robert A Duff
@ 2011-02-07 18:10 0% ` Georg Bauhaus
2011-02-07 19:29 0% ` Dmitry A. Kazakov
1 sibling, 1 reply; 200+ results
From: Georg Bauhaus @ 2011-02-07 18:10 UTC (permalink / raw)
On 07.02.11 16:21, Dmitry A. Kazakov wrote:
>> It means that Ada function Ada.Numerics.Discrete_Random.Random
>> only works because it violates its "contract". The parameter (a
>> generator object) is passed "in", but is modified. Its mutation
>> is one effect of calling function Random.
>
> Wrong. You might have an implementation of Random backed by the hardware in
> which case Random would have no internal state whatsoever.
An implementation does not specify the language. By the language,
Random relies on the fact that whenever it is finished, it will
deliver the "next" value ("from its generator"). The state of a
Generator can be saved and restored, so the notion of its state
is meaningful in the abstract.
Since we are discussion the effects of subprogram specs on programmer
intuition, Random's parameter Gen being of mode "in" is at odds with
the usual meaning of "in".
^ permalink raw reply [relevance 0%]
* Re: How do I write directly to a memory address?
2011-02-07 16:14 5% ` Robert A Duff
@ 2011-02-07 17:23 0% ` Dmitry A. Kazakov
2011-02-07 18:38 0% ` Jeffrey Carter
1 sibling, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2011-02-07 17:23 UTC (permalink / raw)
On Mon, 07 Feb 2011 11:14:29 -0500, Robert A Duff wrote:
> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
>
>> Wrong. You might have an implementation of Random backed by the hardware in
>> which case Random would have no internal state whatsoever.
>
> I don't think a truly random implementation of
> Ada.Numerics. ... .Random would be correct,
> because you're allowed to reset the state to a
> previously-saved state, and replay they exact same sequence
> of pseudo-random numbers.
>
> It might be useful to have a truly-random function, but
> it would have to be a different one.
You are right.
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
^ permalink raw reply [relevance 0%]
* Re: How do I write directly to a memory address?
2011-02-07 14:58 5% ` Georg Bauhaus
2011-02-07 15:21 0% ` Dmitry A. Kazakov
@ 2011-02-07 16:54 0% ` Ludovic Brenta
1 sibling, 0 replies; 200+ results
From: Ludovic Brenta @ 2011-02-07 16:54 UTC (permalink / raw)
Georg Bauhaus wrote:
> Exactly. Style has, by hypothesis, a strong impact on on code
> quality [...]
I would rephrase that as: style has, *in my experience*, a strong
impact on code quality.
>> In Ada, this bad style is simply not possible.
>
> It sure is possible to write awful and dangerous Ada text, even
> with the dangers hidden. While this style is possible, Ada culture
> is less tolerant. (Or, more skeptical of the "practical" programmer.)
In Ada, it is pretty difficult to hide such dangers. In the case I
was talking about, had the subprogram been written in Ada, the
programmer would have had to declare a copy of the "in" argument
explicitly or to make the argument "in out"; both would have made the
bug immediately obvious to any reviewer. The reason why the bug
eluded so many people and survived 15 years was that reviewers failed
to see the assignment as the cause for the bug. Perhaps because they
were tainted by Ada culture where, if you assign to an argument, this
necessarily means the argument is "in out".
You can always program dangerously in Ada but you have to be explicit
about it.
>>> For further ammunition for Verdun style language comparisons,
>>> see function Ada.Numerics.Discrete_Random.Random.
>
>> What does that mean?
>
> It means that Ada function Ada.Numerics.Discrete_Random.Random
> only works because it violates its "contract". The parameter (a
> generator object) is passed "in", but is modified. Its mutation
> is one effect of calling function Random.
The generator is not modified; its associated (pointed-to) state is.
When reviewing a function that takes a pointer (or an object
containing a pointer), I expect and look for writes through the
pointer, so again the bug I was talking about would not have survived
a code review.
>>> I think there are better arguments.
>
>> No.
>
> Yes, and you have named them. They seem to have a little less
> to do with the language definitions, but rather with "encouragement"
> to write your intentions properly.
> (In at least one video (lecture? Ada UK?) Robert Dewar
> has been emphasizing a cultural issue a few times).
Well, I came to wonder what intentions are conveyed by "void foo (int
arg)" and why modifying arg inside foo could be intentional. Since I
came up with no convincing reason (the only reasons being variants of
premature optimization), I concluded that the possibility of "void foo
(int arg)" as opposed to "void foo (const int arg)" was a flaw in the
C language, that cost me a lot of effort.
--
Ludovic Brenta.
^ permalink raw reply [relevance 0%]
* Re: How do I write directly to a memory address?
2011-02-07 15:21 0% ` Dmitry A. Kazakov
@ 2011-02-07 16:14 5% ` Robert A Duff
2011-02-07 17:23 0% ` Dmitry A. Kazakov
2011-02-07 18:38 0% ` Jeffrey Carter
2011-02-07 18:10 0% ` Georg Bauhaus
1 sibling, 2 replies; 200+ results
From: Robert A Duff @ 2011-02-07 16:14 UTC (permalink / raw)
"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
> Wrong. You might have an implementation of Random backed by the hardware in
> which case Random would have no internal state whatsoever.
I don't think a truly random implementation of
Ada.Numerics. ... .Random would be correct,
because you're allowed to reset the state to a
previously-saved state, and replay they exact same sequence
of pseudo-random numbers.
It might be useful to have a truly-random function, but
it would have to be a different one.
- Bob
^ permalink raw reply [relevance 5%]
* Re: How do I write directly to a memory address?
2011-02-07 14:58 5% ` Georg Bauhaus
@ 2011-02-07 15:21 0% ` Dmitry A. Kazakov
2011-02-07 16:14 5% ` Robert A Duff
2011-02-07 18:10 0% ` Georg Bauhaus
2011-02-07 16:54 0% ` Ludovic Brenta
1 sibling, 2 replies; 200+ results
From: Dmitry A. Kazakov @ 2011-02-07 15:21 UTC (permalink / raw)
On Mon, 07 Feb 2011 15:58:44 +0100, Georg Bauhaus wrote:
> No, "in" is intended to mean "in". There are two reasons that
> this is not an unbreakable property. The first is demonstrated by
> Ada.Numerics.Discrete_Random.Random.
This is a poor example, because random number is indeed immutable and has
no intrinsic state. A pseudo-random generator has state, but the thing it
models is stateless. In this sense there is no difference between integer
123 and the random number uniformly distributed on [0,1]. In both cases the
corresponding computational object might have state or not. E.g. literal
can be stored in the volatile memory. Whether such implementation detail
need to be exposed (to have Reset, for example), depends on many factors.
See also Ada.Calendar.Clock.
> It means that Ada function Ada.Numerics.Discrete_Random.Random
> only works because it violates its "contract". The parameter (a
> generator object) is passed "in", but is modified. Its mutation
> is one effect of calling function Random.
Wrong. You might have an implementation of Random backed by the hardware in
which case Random would have no internal state whatsoever.
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
^ permalink raw reply [relevance 0%]
* Re: How do I write directly to a memory address?
2011-02-07 13:56 0% ` Ludovic Brenta
@ 2011-02-07 14:58 5% ` Georg Bauhaus
2011-02-07 15:21 0% ` Dmitry A. Kazakov
2011-02-07 16:54 0% ` Ludovic Brenta
0 siblings, 2 replies; 200+ results
From: Georg Bauhaus @ 2011-02-07 14:58 UTC (permalink / raw)
On 07.02.11 14:56, Ludovic Brenta wrote:
> This bad style had
> a lot of influence on the programmers of 15 years ago whose code I
> must now maintain.
Exactly. Style has, by hypothesis, a strong impact on on code
quality, since programming patterns and programming idioms are
passed on at every stage of becoming outdated. Programmers will
copy idioms with little consideration, especially when idioms
have become associated with revered authors, first edition.
They are not updated. They are also not updated because
compilers will not reject old code.
> In Ada, this bad style is simply not possible.
It sure is possible to write awful and dangerous Ada text, even
with the dangers hidden. While this style is possible, Ada culture
is less tolerant. (Or, more skeptical of the "practical" programmer.)
> In Ada, "in" really means "in".
No, "in" is intended to mean "in". There are two reasons that
this is not an unbreakable property. The first is demonstrated by
Ada.Numerics.Discrete_Random.Random.
But Random is the exception rather than the rule, Ada tradition
promotes the reverse effect of what C tradition promotes, I think:
by Ada's default, by the traditional idiom, "in" stands for "in".
(In the case of void safety, the language discussions include
comments bemoaning that we'll have to write "not null"
instead of marking the reverse case (may be null), thus underlining
the tradition.)
The second reason that "in" need not mean "in" is less brutal:
it is the possibility of write access to a parameter object
from within the function if the objects is also a global object.
(Global to the function). (Whence Ada getting "in out" parameters
for functions is considered an act of honesty, if I understand
comment in ARG mail correctly.) Again, this kind of access is
considered by style (and is also possible in C).
>> For further ammunition for Verdun style language comparisons,
>> see function Ada.Numerics.Discrete_Random.Random.
>
> What does that mean?
It means that Ada function Ada.Numerics.Discrete_Random.Random
only works because it violates its "contract". The parameter (a
generator object) is passed "in", but is modified. Its mutation
is one effect of calling function Random.
>> I think there are better arguments.
>
> No.
Yes, and you have named them. They seem to have a little less
to do with the language definitions, but rather with "encouragement"
to write your intentions properly.
(In at least one video (lecture? Ada UK?) Robert Dewar
has been emphasizing a cultural issue a few times).
^ permalink raw reply [relevance 5%]
* Re: How do I write directly to a memory address?
2011-02-07 13:43 5% ` Georg Bauhaus
@ 2011-02-07 13:56 0% ` Ludovic Brenta
2011-02-07 14:58 5% ` Georg Bauhaus
0 siblings, 1 reply; 200+ results
From: Ludovic Brenta @ 2011-02-07 13:56 UTC (permalink / raw)
Georg Bauhaus wrote on comp.lang.ada:
> In C, if you write
>
> int foo(const int arg) { arg = 3; }
>
> you will get a compile time error.
I know. So? The point is that the "const" was absent in the function I
had to debug, and had been absent for about 15 years. Also, not a lot
libX11 or Motif functions have "const" arguments. This bad style had
a lot of influence on the programmers of 15 years ago whose code I
must now maintain.
In Ada, this bad style is simply not possible. In Ada, "in" really
means "in".
> If you write
>
> int foo(const int* arg) { *arg = 3; }
>
> you will get a compile time error.
I know but bugs are easier to detect because when reviewers see a
pointer argument, they know they have to look out for writes through
the pointer. Even if the pointer is to a "const", since it is
trivially easy to defeat the const-ness.
> For further ammunition for Verdun style language comparisons,
> see function Ada.Numerics.Discrete_Random.Random.
What does that mean?
> I think there are better arguments.
No. There was an old (because difficult to reproduce) bug. I spent
time finding and correcting it. This bug could not have happened in
Ada. This argument is the only relevant one to me.
--
Ludovic Brenta.
^ permalink raw reply [relevance 0%]
* Re: How do I write directly to a memory address?
@ 2011-02-07 13:43 5% ` Georg Bauhaus
2011-02-07 13:56 0% ` Ludovic Brenta
0 siblings, 1 reply; 200+ results
From: Georg Bauhaus @ 2011-02-07 13:43 UTC (permalink / raw)
On 07.02.11 10:00, Ludovic Brenta wrote:
> In Ada, if you write:
>
> procedure Foo (Arg : in Integer) is
> begin
> Arg := 3;
> end Foo;
>
> you get a compile-time error.
>
> void foo (int arg) { arg = 3; }
In C, if you write
int foo(const int arg) {
arg = 3;
}
you will get a compile time error.
If you write
int foo(const int* arg) {
*arg = 3;
}
you will get a compile time error.
For further ammunition for Verdun style language comparisons,
see function Ada.Numerics.Discrete_Random.Random.
I think there are better arguments.
^ permalink raw reply [relevance 5%]
* Re: Random number generation
@ 2010-12-30 15:29 4% ` Georg Bauhaus
0 siblings, 0 replies; 200+ results
From: Georg Bauhaus @ 2010-12-30 15:29 UTC (permalink / raw)
On 30.12.10 13:25, Mart van de Wege wrote:
> Georg Bauhaus <rm.dash-bauhaus@futureapps.de> writes:
>>
>> OTOH, the Size parameter is fixed at 6, so subtype Die_Size and
>> the generator could be placed outside Roll. Anyway, another
>> nest will give suitable life times to the objects involved.
>>
> How does that work?
Using another level of nesting to control life time
and parameterization:
procedure Rolltest is
procedure Setup_And_Roll (Size: Positive) is
subtype Die_Size is Positive range 2..Size;
package Die is new Ada.Numerics.Discrete_Random( Die_Size );
G : Die.Generator;
function Roll ( Number : in Positive;
Modifier : in Integer := 0 ) return Integer is
Result : Integer;
Temp : Integer;
begin
Result := 0;
for I in 1..Number loop
Temp := Die.Random(G);
Result := Result + Temp;
end loop;
Result := Result + Modifier;
return Result;
end Roll;
begin
Die.Reset(G);
for I in 1..10 loop
Put(Roll( Number => 3 ));
end loop;
end Setup_And_Roll;
begin
Setup_And_Roll (Size => 6);
end Rolltest;
^ permalink raw reply [relevance 4%]
* Re: Random number generation
2010-12-30 10:43 6% Random number generation Mart van de Wege
2010-12-30 11:34 0% ` Niklas Holsti
2010-12-30 11:51 4% ` Brian Drummond
@ 2010-12-30 13:04 5% ` Dmitry A. Kazakov
2 siblings, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2010-12-30 13:04 UTC (permalink / raw)
On Thu, 30 Dec 2010 11:43:40 +0100, Mart van de Wege wrote:
> Anyone care to at least point me to some documentation that explains
> what I'm doing wrong?
Random generator is a stateful object, thus it cannot be local.
I suggest this is what you want:
--------------------------------------------------------------------------
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with Ada.Numerics.Discrete_Random;
procedure Rolltest is
package Uniform is new Ada.Numerics.Discrete_Random (Natural);
use Uniform;
function Roll
( Dice : Generator;
Number : in Positive;
Size : in Positive;
Modifier : in Integer := 0
) return Integer is
Result : Integer := 0;
begin
for I in 1..Number loop
Result := Result + Random (Dice) mod Size;
end loop;
Result := Result + Modifier + Number;
return Result;
end Roll;
Dice : Generator;
begin
Reset (Dice);
for I in 1..10 loop
Put (Roll (Dice => Dice, Number => 3, Size => 6));
end loop;
end Rolltest;
-------------------------------------------------------------------------
I added Number to the accumulated result because you did so in your example
by choosing the range 2..Size.
BTW, a sum of n realizations of a uniformly distributed random number is
distributed uniformly with the factor n. So you need not to run a cycle
within Roll:
function Roll
( Dice : Generator;
Number : in Positive;
Size : in Positive;
Modifier : in Integer := 0
) return Integer is
begin
return Number * ((Random (Dice) mod Size) + 1) + Modifier;
end Roll;
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
^ permalink raw reply [relevance 5%]
* Re: Random number generation
2010-12-30 11:51 4% ` Brian Drummond
@ 2010-12-30 12:16 0% ` Mart van de Wege
0 siblings, 0 replies; 200+ results
From: Mart van de Wege @ 2010-12-30 12:16 UTC (permalink / raw)
Brian Drummond <brian_drummond@btconnect.com> writes:
> On Thu, 30 Dec 2010 11:43:40 +0100, Mart van de Wege <mvdwege@mail.com> wrote:
>
<snip>
> Check the documentation for Ada.Numerics.Discrete_Random or at least its
> specification ( .ads file) but I think you'll find you need to reset the Die
> exactly once, rather than every call of the Roll function.
>
> As I understand, you are resetting the seed each time, so you get the same
> results!
>
> The shortest way to resolve this is to make Die a global variable and reset it
> at the start of the main program - in the context of a one-page beginner's
> program it's a reasonable thing to do.
>
> We're all taught "Global Variables are BAD" with good reason, so - once you have
> resolved the immediate problem - it might be a good time to learn a bit about
> packages, to hide the Die and expose only what you need to operate on it.
>
Heh.
This function *was* living in a package. I abstracted it out into a
test program to isolate it and make it short enough to copy/paste here.
But thanks. The problem is with my re-initialising the generator every time,
and like others pointed out, the code is running fast enough that the
generator gets the same seed every time; that is, if I understand
everything correctly now.
Mart
--
"We will need a longer wall when the revolution comes."
--- AJS, quoting an uncertain source.
^ permalink raw reply [relevance 0%]
* Re: Random number generation
2010-12-30 10:43 6% Random number generation Mart van de Wege
2010-12-30 11:34 0% ` Niklas Holsti
@ 2010-12-30 11:51 4% ` Brian Drummond
2010-12-30 12:16 0% ` Mart van de Wege
2010-12-30 13:04 5% ` Dmitry A. Kazakov
2 siblings, 1 reply; 200+ results
From: Brian Drummond @ 2010-12-30 11:51 UTC (permalink / raw)
On Thu, 30 Dec 2010 11:43:40 +0100, Mart van de Wege <mvdwege@mail.com> wrote:
>Beginner's question: I'm trying to implement a function that rolls a
>number of dice and then adds a modifier. Somehow, it produces the same
>number every time. I can't see where I'm going wrong.
>
>Here's the proof of concept code:
>
>with Ada.Numerics.Discrete_Random,Ada.Integer_Text_IO;
>use Ada.Integer_Text_IO;
>
>procedure Rolltest is
> function Roll ( Number : in Positive;
...
> package Die is new Ada.Numerics.Discrete_Random( Die_Size );
...
> begin
> Die.Reset(G);
...
> end Roll;
>begin
> for I in 1..10 loop
> Put(Roll( Number => 3, Size => 6 ));
> end loop;
>end Rolltest;
>
>Anyone care to at least point me to some documentation that explains
>what I'm doing wrong?
Check the documentation for Ada.Numerics.Discrete_Random or at least its
specification ( .ads file) but I think you'll find you need to reset the Die
exactly once, rather than every call of the Roll function.
As I understand, you are resetting the seed each time, so you get the same
results!
The shortest way to resolve this is to make Die a global variable and reset it
at the start of the main program - in the context of a one-page beginner's
program it's a reasonable thing to do.
We're all taught "Global Variables are BAD" with good reason, so - once you have
resolved the immediate problem - it might be a good time to learn a bit about
packages, to hide the Die and expose only what you need to operate on it.
Essentially, within the package, Die can safely become a "global" variable, but
invisible and inaccessible outside the package, so that it appears more like a
static variable in a C function (holds the current random seed value between
calls).
- Brian
^ permalink raw reply [relevance 4%]
* Re: Random number generation
2010-12-30 10:43 6% Random number generation Mart van de Wege
@ 2010-12-30 11:34 0% ` Niklas Holsti
2010-12-30 11:51 4% ` Brian Drummond
2010-12-30 13:04 5% ` Dmitry A. Kazakov
2 siblings, 1 reply; 200+ results
From: Niklas Holsti @ 2010-12-30 11:34 UTC (permalink / raw)
Mart van de Wege wrote:
> Beginner's question: I'm trying to implement a function that rolls a
> number of dice and then adds a modifier. Somehow, it produces the same
> number every time. I can't see where I'm going wrong.
>
> Here's the proof of concept code:
>
> with Ada.Numerics.Discrete_Random,Ada.Integer_Text_IO;
> use Ada.Integer_Text_IO;
>
> procedure Rolltest is
> function Roll ( Number : in Positive;
> Size : in Positive;
> Modifier : in Integer := 0 ) return Integer is
> subtype Die_Size is Positive range 2..Size;
> package Die is new Ada.Numerics.Discrete_Random( Die_Size );
> G : Die.Generator;
> Result : Integer;
> Temp : Integer;
> begin
> Die.Reset(G);
This Reset operation is specified (in RM A.5.2(34)) to set the state of
the generator G to a "time-dependent" state.
If every call of Roll is returning the same results, perhaps the calls
happen so rapidly that whatever discrete "time" source Reset uses is the
same on each call, thus setting G to the same state on each call.
Ordinarily I would suggest to call Reset just once, and then let the
state of the generator evolve without Resets over all calls of Roll, but
this cannot be done here because G is a local variable in Roll, and it
must be so since the generic actual parameter depends on the Size
parameter of Roll.
Perhaps you should make another random Integer number generator IntGen,
local to Rolltest but not to Roll, and use the generated Integer numbers
to initialize Roll.G by a Reset call that has the random Integer as the
second, state-determining "Initiator" parameter. The IntGen generator
should be Reset in Rolltest, not in Roll, or left in its default initial
state.
If you leave a random-number generator with its default initial state
(no Reset call), you get the same random-number sequence on every execution.
If you use the single-parameter Reset (G) procedure, you get a sequence
that is different for different executions, providing that the Resets
are far enough apart in time to make a difference.
> Result := 0;
> for I in 1..Number loop
> Temp := Die.Random(G);
> Result := Result + Temp;
> end loop;
> Result := Result + Modifier;
> return Result;
> end Roll;
> begin
> for I in 1..10 loop
> Put(Roll( Number => 3, Size => 6 ));
> end loop;
> end Rolltest;
>
> Anyone care to at least point me to some documentation that explains
> what I'm doing wrong?
>
> Mart
>
--
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
. @ .
^ permalink raw reply [relevance 0%]
* Random number generation
@ 2010-12-30 10:43 6% Mart van de Wege
2010-12-30 11:34 0% ` Niklas Holsti
` (2 more replies)
0 siblings, 3 replies; 200+ results
From: Mart van de Wege @ 2010-12-30 10:43 UTC (permalink / raw)
Beginner's question: I'm trying to implement a function that rolls a
number of dice and then adds a modifier. Somehow, it produces the same
number every time. I can't see where I'm going wrong.
Here's the proof of concept code:
with Ada.Numerics.Discrete_Random,Ada.Integer_Text_IO;
use Ada.Integer_Text_IO;
procedure Rolltest is
function Roll ( Number : in Positive;
Size : in Positive;
Modifier : in Integer := 0 ) return Integer is
subtype Die_Size is Positive range 2..Size;
package Die is new Ada.Numerics.Discrete_Random( Die_Size );
G : Die.Generator;
Result : Integer;
Temp : Integer;
begin
Die.Reset(G);
Result := 0;
for I in 1..Number loop
Temp := Die.Random(G);
Result := Result + Temp;
end loop;
Result := Result + Modifier;
return Result;
end Roll;
begin
for I in 1..10 loop
Put(Roll( Number => 3, Size => 6 ));
end loop;
end Rolltest;
Anyone care to at least point me to some documentation that explains
what I'm doing wrong?
Mart
--
"We will need a longer wall when the revolution comes."
--- AJS, quoting an uncertain source.
^ permalink raw reply [relevance 6%]
* Task execution time 2
@ 2010-12-30 8:54 5% Dmitry A. Kazakov
0 siblings, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2010-12-30 8:54 UTC (permalink / raw)
Here is a better test for the thing. It measures the execution time using
real-time clock and Windows services. The idea is to give up the processor
after 0.5ms, before the system time quant expires.
The test must run considerably long time. Because the task Measured should
lose the processor each 0.5ms and return back after other tasks would take
their share. If the test completes shortly, that possibly mean something
wrong. Increase the number of worker task.
----------------------------------------------------------------
with Ada.Execution_Time; use Ada.Execution_Time;
with Ada.Real_Time; use Ada.Real_Time;
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Numerics.Elementary_Functions;
procedure Executuion_Time_1 is
task type Measured;
task body Measured is
Count : Seconds_Count;
Fraction : Time_Span;
Estimated : Time_Span := Time_Span_Zero;
Start : Time;
begin
for I in 1..1_000 loop
Start := Clock;
while To_Duration (Clock - Start) < 0.000_5 loop
null;
end loop;
Estimated := Estimated + Clock - Start;
delay 0.0;
end loop;
Split (Ada.Execution_Time.Clock, Count, Fraction);
Put_Line
( "Measured: seconds" & Seconds_Count'Image (Count) &
" Fraction " & Duration'Image (To_Duration (Fraction))
);
Put_Line
( "Estimated:" & Duration'Image (To_Duration (Estimated))
);
end Measured;
task type Worker; -- Used to generate CPU load
task body Worker is
use Ada.Numerics.Elementary_Functions;
X : Float;
begin
for I in Positive'Range loop
X := sin (Float (I));
end loop;
end Worker;
begin
delay 0.1;
declare
Workers : array (1..5) of Worker;
Test : Measured;
begin
null;
end;
end Executuion_Time_1;
-----------------------------------------------------------
Windows XP SP3
Measured: seconds 0 Fraction 0.000000000
Estimated: 0.690618774
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
^ permalink raw reply [relevance 5%]
* Task execution time test
@ 2010-12-26 10:25 5% Dmitry A. Kazakov
0 siblings, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2010-12-26 10:25 UTC (permalink / raw)
Here is a small test for task execution time.
Five worker tasks are used to generate background CPU load. When the
measured task enters delay 0.1ms (on a system where delay is non-busy) it
should lose the CPU prematurely.
Under at least some Windows systems the test might fail because Windows
performance counters are CPU quants 1ms or 10ms, depending on settings.
Under VxWorks the test may fail because real-time clock there is driven by
the timer interrupts, so it is impossible to have non-busy wait for 0.1ms.
(I cannot say anything about Linux, because I never used it for RT
applications, maybe other people could comment)
----------------------------------------------------
with Ada.Execution_Time; use Ada.Execution_Time;
with Ada.Real_Time; use Ada.Real_Time;
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Numerics.Elementary_Functions;
procedure Executuion_Time is
task type Measured;
task body Measured is
Count : Seconds_Count;
Fraction : Time_Span;
begin
for I in 1..1_000 loop
delay 0.000_1;
end loop;
Split (Ada.Execution_Time.Clock, Count, Fraction);
Put_Line
( "Seconds" & Seconds_Count'Image (Count) &
" Fraction" & Duration'Image (To_Duration (Fraction))
);
end Measured;
task type Worker; -- Used to generate CPU load
task body Worker is
use Ada.Numerics.Elementary_Functions;
X : Float;
begin
for I in Positive'Range loop
X := sin (Float (I));
end loop;
end Worker;
begin
delay 0.1; -- This might be needed for some buggy versions of GNAT
declare
Workers : array (1..5) of Worker;
Test : Measured;
begin
null;
end;
end Executuion_Time;
-----------------------------------------------------
On my Windows XP SP3 the test yields 0-0.
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
^ permalink raw reply [relevance 5%]
* Re: How to include vector operators?
2010-12-06 21:37 5% ` Adam Beneschan
@ 2010-12-07 11:11 0% ` tolkamp
0 siblings, 0 replies; 200+ results
From: tolkamp @ 2010-12-07 11:11 UTC (permalink / raw)
On 6 dec, 22:37, Adam Beneschan <a...@irvine.com> wrote:
> On Dec 6, 1:03 pm, tolkamp <f.tolk...@gmail.com> wrote:
>
>
>
>
>
> > In my application the package Ada.Numerics.Generic_Real_Arrays is
> > included.
>
> > Code:
>
> > with Ada.Numerics.Generic_Real_Arrays;
> > package Vectors is new Ada.Numerics.Generic_Real_Arrays(Float);
>
> > How to include the vector operators like "+" and "-" ?
>
> > I tried the follwing:
> > function "+" (Left, Right : Vectors.Real_Vector) return
> > Vectors.Real_Vector
> > renames
> > Ada.Numerics.Generic_Real_Arrays.Instantiations."+";
>
> > However this gives the error:
> > invalid prefix in selected component "Generic_Real_Arrays".
>
> function "+" (Left, Right : Vectors.Real_Vector) return
> Vectors.Real_Vector
> renames Vectors."+";
>
> But you probably really want to use this, which will make all the
> operators visible:
>
> use type Vectors.Real_Vector;
>
> (and maybe the same for Real_Matrix).
>
> But NOT this:
>
> use type Ada.Numerics.Generic_Real_Arrays.Real_Vector;
>
> You can't access declarations in a generic package directly. You have
> to access the declarations in a generic *instance*.
>
> -- Adam- Tekst uit oorspronkelijk bericht niet weergeven -
>
> - Tekst uit oorspronkelijk bericht weergeven -
Thank you for your solution. Now it works correct.
Fred
^ permalink raw reply [relevance 0%]
* Re: How to include vector operators?
2010-12-06 21:03 7% How to include vector operators? tolkamp
2010-12-06 21:37 5% ` Adam Beneschan
@ 2010-12-07 2:53 0% ` Gautier write-only
1 sibling, 0 replies; 200+ results
From: Gautier write-only @ 2010-12-07 2:53 UTC (permalink / raw)
> with Ada.Numerics.Generic_Real_Arrays;
Since it's generic, you can't use it directly. It's why you have:
> package Vectors is new Ada.Numerics.Generic_Real_Arrays(Float);
>
> How to include the vector operators like "+" and "-" ?
I guess you want to write things like (i):
u+v
whereas now you need to write (ii)
Vectors."+"(u,v)
To be able to write the form (i), you can put
use Vectors;
after the above definition (package Vectors is new ...)
and you'll be happy.
______________________________________________________________
Gautier's Ada programming -- http://gautiersblog.blogspot.com/
NB: follow the above link for a working e-mail address
^ permalink raw reply [relevance 0%]
* Re: How to include vector operators?
2010-12-06 21:03 7% How to include vector operators? tolkamp
@ 2010-12-06 21:37 5% ` Adam Beneschan
2010-12-07 11:11 0% ` tolkamp
2010-12-07 2:53 0% ` Gautier write-only
1 sibling, 1 reply; 200+ results
From: Adam Beneschan @ 2010-12-06 21:37 UTC (permalink / raw)
On Dec 6, 1:03 pm, tolkamp <f.tolk...@gmail.com> wrote:
> In my application the package Ada.Numerics.Generic_Real_Arrays is
> included.
>
> Code:
>
> with Ada.Numerics.Generic_Real_Arrays;
> package Vectors is new Ada.Numerics.Generic_Real_Arrays(Float);
>
> How to include the vector operators like "+" and "-" ?
>
> I tried the follwing:
> function "+" (Left, Right : Vectors.Real_Vector) return
> Vectors.Real_Vector
> renames
> Ada.Numerics.Generic_Real_Arrays.Instantiations."+";
>
> However this gives the error:
> invalid prefix in selected component "Generic_Real_Arrays".
function "+" (Left, Right : Vectors.Real_Vector) return
Vectors.Real_Vector
renames Vectors."+";
But you probably really want to use this, which will make all the
operators visible:
use type Vectors.Real_Vector;
(and maybe the same for Real_Matrix).
But NOT this:
use type Ada.Numerics.Generic_Real_Arrays.Real_Vector;
You can't access declarations in a generic package directly. You have
to access the declarations in a generic *instance*.
-- Adam
^ permalink raw reply [relevance 5%]
* How to include vector operators?
@ 2010-12-06 21:03 7% tolkamp
2010-12-06 21:37 5% ` Adam Beneschan
2010-12-07 2:53 0% ` Gautier write-only
0 siblings, 2 replies; 200+ results
From: tolkamp @ 2010-12-06 21:03 UTC (permalink / raw)
In my application the package Ada.Numerics.Generic_Real_Arrays is
included.
Code:
with Ada.Numerics.Generic_Real_Arrays;
package Vectors is new Ada.Numerics.Generic_Real_Arrays(Float);
How to include the vector operators like "+" and "-" ?
I tried the follwing:
function "+" (Left, Right : Vectors.Real_Vector) return
Vectors.Real_Vector
renames
Ada.Numerics.Generic_Real_Arrays.Instantiations."+";
However this gives the error:
invalid prefix in selected component "Generic_Real_Arrays".
^ permalink raw reply [relevance 7%]
* Re: Large arrays passed to arithmetic operators overflows GNAT stack
2010-12-04 14:17 0% ` Peter C. Chapin
@ 2010-12-05 1:22 4% ` Jerry
0 siblings, 0 replies; 200+ results
From: Jerry @ 2010-12-05 1:22 UTC (permalink / raw)
On Dec 4, 7:17 am, "Peter C. Chapin" <PCha...@vtc.vsc.edu> wrote:
> On 2010-12-04 01:32, Jerry wrote:
>
> > with
> > Ada.Numerics.Long_Real_Arrays;
> > use
> > Ada.Numerics.Long_Real_Arrays;
> > procedure array_test is
> > type Real_Vector_Access is access Real_Vector;
> > N : Integer := 1_048_130;
> > t_Ptr : Real_Vector_Access := new Real_Vector(0 .. N);
> > t : Real_Vector renames t_Ptr.all;
>
> I don't think you need this renaming. If you do t_Ptr'Range or t_Ptr(i)
> the compiler will forward those operations directly to the object.
> ...
> Peter
That is true but the renaming is still convenient for other reasons.
For example,
the lines
t : Real_Vector_Access := new Real_Vector(0 .. N);
t_Diff : Real_Vector_Access := new Real_Vector(0 .. N - 1);
...
[Line 14] t_Diff := t(1 .. N);
causes the complaints
expected type "Real_Vector_Access" defined at line 14
found type "Ada.Numerics.Generic_Real_Arrays.Real_Vector" from
instance at a-nlrear.ads:18
And passing t to a vector cosine (e.g.) function that expects to see a
Real_Vector will also fail. Of course, with two like pointers t and x,
assignment t := x assigns the pointers, not the array contents, and
with three like pointers t, x, y, t := x - y fails to find an
applicable operator function.
This clever renaming trick was mentioned by Brian Drummond in this
thread:
http://groups.google.com/group/comp.lang.ada/browse_thread/thread/ae395e5c11de7bc9/bda8d61bd3a66ee9?hl=en&q=Jerry+stack&lnk=nl&
Jerry
^ permalink raw reply [relevance 4%]
* Re: Large arrays passed to arithmetic operators overflows GNAT stack
2010-12-04 6:32 5% Large arrays passed to arithmetic operators overflows GNAT stack Jerry
2010-12-04 9:19 0% ` Vinzent Hoefler
@ 2010-12-04 14:17 0% ` Peter C. Chapin
2010-12-05 1:22 4% ` Jerry
1 sibling, 1 reply; 200+ results
From: Peter C. Chapin @ 2010-12-04 14:17 UTC (permalink / raw)
On 2010-12-04 01:32, Jerry wrote:
> with
> Ada.Numerics.Long_Real_Arrays;
> use
> Ada.Numerics.Long_Real_Arrays;
> procedure array_test is
> type Real_Vector_Access is access Real_Vector;
> N : Integer := 1_048_130;
> t_Ptr : Real_Vector_Access := new Real_Vector(0 .. N);
> t : Real_Vector renames t_Ptr.all;
I don't think you need this renaming. If you do t_Ptr'Range or t_Ptr(i)
the compiler will forward those operations directly to the object.
> t_Diff_Ptr : Real_Vector_Access := new Real_Vector(0 .. N - 1);
> t_Diff : Real_Vector renames t_Diff_Ptr.all;
> begin
> for i in t'range loop
> t(i) := 1.0;
> end loop;
> t_Diff := t(1 .. N) - t(0 .. N - 1);
I believe a temporary object (on the stack) needs to be created here to
hold the result of the difference before it gets assigned to t_Diff. So
despite the fact that the result is ultimately stored on the heap it
ends up passing through the stack on its way. If I'm correct it's not
the subtraction operator itself that is causing the problem but rather
what is happening with the result.
In short "-" is returning the array by value and not an access to the
array. The compiler has to figure out what to do with that value before
assigning it to t_Diff and it is using a stack temporary.
Peter
^ permalink raw reply [relevance 0%]
* Re: Large arrays passed to arithmetic operators overflows GNAT stack
2010-12-04 6:32 5% Large arrays passed to arithmetic operators overflows GNAT stack Jerry
@ 2010-12-04 9:19 0% ` Vinzent Hoefler
2010-12-04 14:17 0% ` Peter C. Chapin
1 sibling, 0 replies; 200+ results
From: Vinzent Hoefler @ 2010-12-04 9:19 UTC (permalink / raw)
Jerry wrote:
> with
> Ada.Numerics.Long_Real_Arrays;
> use
> Ada.Numerics.Long_Real_Arrays;
> procedure array_test is
> type Real_Vector_Access is access Real_Vector;
> N : Integer := 1_048_130;
[...]
> begin
> for i in t'range loop
> t(i) := 1.0;
> end loop;
> t_Diff := t(1 .. N) - t(0 .. N - 1);
> end array_test;
It's probably not the operator call that crashes, but the creation of
the temporary arrays t(...). Couple of days ago, I stumbled upon a
similar problem with aggegrate assignments:
-- Do array initialization in a loop.
-- If it's done with an aggregate assignment, GNAT raises Storage_Error
-- during elaboration.
> Another fix would be to write operator procedures that specifically
> take pointers as arguments; that would possibly be the only fix for
> arrays that still overflow the stack when it is maxed out.
This wouldn't help here, I suppose.
Vinzent.
--
Beaten by the odds since 1974.
^ permalink raw reply [relevance 0%]
* Large arrays passed to arithmetic operators overflows GNAT stack
@ 2010-12-04 6:32 5% Jerry
2010-12-04 9:19 0% ` Vinzent Hoefler
2010-12-04 14:17 0% ` Peter C. Chapin
0 siblings, 2 replies; 200+ results
From: Jerry @ 2010-12-04 6:32 UTC (permalink / raw)
For what it's worth, passing large numerical arrays to the arithmetic
operators in GNAT can cause the stack to overflow (segfault) even when
the arrays are allocated from the heap. I suppose that indicates that
they are being copied rather than being passed by reference.
For example, on OS X which has a default stack size of 8192 KB, the
following program segfaults when N is greater than about 1_048_138
(about 8 MB per Long_Float array) but runs OK when it is somewhat less
than that number.
with
Ada.Numerics.Long_Real_Arrays;
use
Ada.Numerics.Long_Real_Arrays;
procedure array_test is
type Real_Vector_Access is access Real_Vector;
N : Integer := 1_048_130;
t_Ptr : Real_Vector_Access := new Real_Vector(0 .. N);
t : Real_Vector renames t_Ptr.all;
t_Diff_Ptr : Real_Vector_Access := new Real_Vector(0 .. N - 1);
t_Diff : Real_Vector renames t_Diff_Ptr.all;
begin
for i in t'range loop
t(i) := 1.0;
end loop;
t_Diff := t(1 .. N) - t(0 .. N - 1);
end array_test;
The quick fix (in my case) is to increase the stack size from the
shell:
ulimit -s 65532
or whatever is appropriate for your machine--65532 is the hard limit
set by OS X.
Another way to expand the stack without invoking shell commands, as
noted by Björn Persson on this thread
http://groups.google.com/group/comp.lang.ada/browse_thread/thread/ae395e5c11de7bc9/bda8d61bd3a66ee9?hl=en&q=Jerry+stack&lnk=nl&
is to call getrlimit and/or setrlimit from within the program, linking
to these POSIX C routines.
Another fix would be to write operator procedures that specifically
take pointers as arguments; that would possibly be the only fix for
arrays that still overflow the stack when it is maxed out.
As usual, taking the dumb-guy approach, this seems like an unnecessary
nuisance.
Jerry
^ permalink raw reply [relevance 5%]
* Re: GNAT's Protected Objects
2010-11-08 22:32 5% ` Jeffrey Carter
@ 2010-11-09 1:50 0% ` Anh Vo
0 siblings, 0 replies; 200+ results
From: Anh Vo @ 2010-11-09 1:50 UTC (permalink / raw)
On Nov 8, 2:32 pm, Jeffrey Carter <spam.jrcarter....@spam.not.acm.org>
wrote:
> On 11/08/2010 02:38 PM, Anh Vo wrote:
>
>
>
> > How may tasks used, two or four, when slowness was observed when
> > compared to simple task? I will be supprised if the answer is two. It
> > is logically expected that two tasks should perform better than single
> > task. However, when it comes to four or greater task, the result may
> > not be true due to task switching cost.
>
> That's what I expected. However, any number of tasks > 1 took longer than a
> single task.
>
> > I would be glad to test it on my two core CPU mahine if the your
> > little program is posted.
>
> I have appended the code to this message. Watch for line wrapping.
>
> --
> Jeff Carter
> "Sir Robin the not-quite-so-brave-as-Sir-Lancelot,
> who had nearly fought the Dragon of Angnor,
> who nearly stood up to the vicious Chicken of Bristol,
> and who had personally wet himself at the
> Battle of Badon Hill."
> Monty Python & the Holy Grail
> 68
>
> with Ada.Exceptions;
> with Ada.Numerics.Float_Random;
> with Ada.Real_Time;
> with Ada.Text_IO;
>
> with System.Task_Info;
>
> procedure MP_Mult_PO is
> Num_Processors : constant Positive := System.Task_Info.Number_Of_Processors;
>
> subtype Index_Value is Integer range 1 .. 500;
>
> type Matrix is array (Index_Value, Index_Value) of Float;
>
> function Mult (Left : in Matrix; Right : in Matrix; Num_Tasks : in Positive)
> return Matrix;
> -- Perform a concurrent multiplication of Left * Right using Num_Tasks tasks
>
> function Mult (Left : in Matrix; Right : in Matrix; Num_Tasks : in Positive)
> return Matrix is
> task type Calc_One;
>
> protected Control is
> procedure Get (Row : out Natural; Col : out Natural);
> -- Returns the row and column of a result to calculate.
> -- Returns zero for both when there are no more results to calculate.
> private -- Control
> Next_Row : Positive := 1;
> Next_Col : Positive := 1;
> Done : Boolean := False;
> end Control;
>
> Result : Matrix;
>
> task body Calc_One is
> Row : Natural;
> Col : Natural;
> begin -- Calc_One
> All_Results : loop
> Control.Get (Row => Row, Col => Col);
>
> exit All_Results when Row = 0;
>
> Result (Row, Col) := 0.0;
>
> Sum : for K in Index_Value loop
> Result (Row, Col) := Result (Row, Col) + Left (Row, K) * Right
> (K, Col);
> end loop Sum;
> end loop All_Results;
> exception -- Calc_One
> when E : others =>
> Ada.Text_IO.Put_Line (Item => "Calc_One " &
> Ada.Exceptions.Exception_Information (E) );
> end Calc_One;
>
> protected body Control is
> procedure Get (Row : out Natural; Col : out Natural) is
> begin -- Get
> if Done then
> Row := 0;
> Col := 0;
>
> return;
> end if;
>
> Row := Next_Row;
> Col := Next_Col;
>
> if Next_Col < Index_Value'Last then
> Next_Col := Next_Col + 1;
>
> return;
> end if;
>
> Next_Col := 1;
> Next_Row := Next_Row + 1;
>
> Done := Next_Row > Index_Value'Last;
> end Get;
> end Control;
> begin -- Mult
> Create_Tasks : declare
> type Task_List is array (1 .. Num_Tasks) of Calc_One;
>
> Tasks : Task_List;
> begin -- Create_Tasks
> null; -- Wait for all tasks to complete
> end Create_Tasks;
>
> return Result;
> exception -- Mult
> when E : others =>
> Ada.Text_IO.Put_Line (Item => "Mult " &
> Ada.Exceptions.Exception_Information (E) );
>
> raise;
> end Mult;
>
> function Random return Float;
>
> Gen : Ada.Numerics.Float_Random.Generator;
>
> function Random return Float is
> begin -- Random
> return 200.0 * Ada.Numerics.Float_Random.Random (Gen) - 100.0; -- -100 ..
> 100.
> end Random;
>
> A : constant Matrix := Matrix'(others => (others => Random) );
> B : constant Matrix := Matrix'(others => (others => Random) );
>
> C : Matrix;
>
> Elapsed : Duration;
> Prev : Duration := Duration'Last;
> Start : Ada.Real_Time.Time;
> Num_Tasks : Positive := 1;
>
> use type Ada.Real_Time.Time;
> begin -- MP_Mult_PO
> Ada.Text_IO.Put_Line (Item => "Num processors" & Integer'Image
> (Num_Processors) );
>
> All_Calls : loop
> Start := Ada.Real_Time.Clock;
> C := Mult (A, B, Num_Tasks);
> Elapsed := Ada.Real_Time.To_Duration (Ada.Real_Time.Clock - Start);
> Ada.Text_IO.Put_Line (Item => Integer'Image (Num_Tasks) & ' ' &
> Duration'Image (Elapsed) );
>
> exit All_Calls when Num_Tasks > 2 * Num_Processors and Elapsed > Prev;
>
> Prev := Elapsed;
> Num_Tasks := Num_Tasks + 1;
> end loop All_Calls;
> exception -- MP_Mult_PO
> when E : others =>
> Ada.Text_IO.Put_Line (Item => "MP_Mult_PO " &
> Ada.Exceptions.Exception_Information (E) );
> end MP_Mult_PO;
Below are the test results conducted on GNAT 2010 running on Windows
XP.
Num processors 2
1 0.077000009
2 0.055627741
3 0.023719495
4 0.018366580
5 0.018512129
The output looks reasonable. The speed is improved up to 4 tasks. It
slows down with 5 tasks due to tasking switch. However, it is still
better than single task.
As Robert suggested, I would divide work among tasks by passing
paramter into each task. For example, in case of two tasks, one task
handles from rows 1 .. 250 while the other task handle from rows
251 .. 500. By the way, the protected singleton type Control is no
longer needed.
Anh Vo
^ permalink raw reply [relevance 0%]
* Re: GNAT's Protected Objects
@ 2010-11-08 22:32 5% ` Jeffrey Carter
2010-11-09 1:50 0% ` Anh Vo
0 siblings, 1 reply; 200+ results
From: Jeffrey Carter @ 2010-11-08 22:32 UTC (permalink / raw)
On 11/08/2010 02:38 PM, Anh Vo wrote:
>
> How may tasks used, two or four, when slowness was observed when
> compared to simple task? I will be supprised if the answer is two. It
> is logically expected that two tasks should perform better than single
> task. However, when it comes to four or greater task, the result may
> not be true due to task switching cost.
That's what I expected. However, any number of tasks > 1 took longer than a
single task.
> I would be glad to test it on my two core CPU mahine if the your
> little program is posted.
I have appended the code to this message. Watch for line wrapping.
--
Jeff Carter
"Sir Robin the not-quite-so-brave-as-Sir-Lancelot,
who had nearly fought the Dragon of Angnor,
who nearly stood up to the vicious Chicken of Bristol,
and who had personally wet himself at the
Battle of Badon Hill."
Monty Python & the Holy Grail
68
with Ada.Exceptions;
with Ada.Numerics.Float_Random;
with Ada.Real_Time;
with Ada.Text_IO;
with System.Task_Info;
procedure MP_Mult_PO is
Num_Processors : constant Positive := System.Task_Info.Number_Of_Processors;
subtype Index_Value is Integer range 1 .. 500;
type Matrix is array (Index_Value, Index_Value) of Float;
function Mult (Left : in Matrix; Right : in Matrix; Num_Tasks : in Positive)
return Matrix;
-- Perform a concurrent multiplication of Left * Right using Num_Tasks tasks
function Mult (Left : in Matrix; Right : in Matrix; Num_Tasks : in Positive)
return Matrix is
task type Calc_One;
protected Control is
procedure Get (Row : out Natural; Col : out Natural);
-- Returns the row and column of a result to calculate.
-- Returns zero for both when there are no more results to calculate.
private -- Control
Next_Row : Positive := 1;
Next_Col : Positive := 1;
Done : Boolean := False;
end Control;
Result : Matrix;
task body Calc_One is
Row : Natural;
Col : Natural;
begin -- Calc_One
All_Results : loop
Control.Get (Row => Row, Col => Col);
exit All_Results when Row = 0;
Result (Row, Col) := 0.0;
Sum : for K in Index_Value loop
Result (Row, Col) := Result (Row, Col) + Left (Row, K) * Right
(K, Col);
end loop Sum;
end loop All_Results;
exception -- Calc_One
when E : others =>
Ada.Text_IO.Put_Line (Item => "Calc_One " &
Ada.Exceptions.Exception_Information (E) );
end Calc_One;
protected body Control is
procedure Get (Row : out Natural; Col : out Natural) is
begin -- Get
if Done then
Row := 0;
Col := 0;
return;
end if;
Row := Next_Row;
Col := Next_Col;
if Next_Col < Index_Value'Last then
Next_Col := Next_Col + 1;
return;
end if;
Next_Col := 1;
Next_Row := Next_Row + 1;
Done := Next_Row > Index_Value'Last;
end Get;
end Control;
begin -- Mult
Create_Tasks : declare
type Task_List is array (1 .. Num_Tasks) of Calc_One;
Tasks : Task_List;
begin -- Create_Tasks
null; -- Wait for all tasks to complete
end Create_Tasks;
return Result;
exception -- Mult
when E : others =>
Ada.Text_IO.Put_Line (Item => "Mult " &
Ada.Exceptions.Exception_Information (E) );
raise;
end Mult;
function Random return Float;
Gen : Ada.Numerics.Float_Random.Generator;
function Random return Float is
begin -- Random
return 200.0 * Ada.Numerics.Float_Random.Random (Gen) - 100.0; -- -100 ..
100.
end Random;
A : constant Matrix := Matrix'(others => (others => Random) );
B : constant Matrix := Matrix'(others => (others => Random) );
C : Matrix;
Elapsed : Duration;
Prev : Duration := Duration'Last;
Start : Ada.Real_Time.Time;
Num_Tasks : Positive := 1;
use type Ada.Real_Time.Time;
begin -- MP_Mult_PO
Ada.Text_IO.Put_Line (Item => "Num processors" & Integer'Image
(Num_Processors) );
All_Calls : loop
Start := Ada.Real_Time.Clock;
C := Mult (A, B, Num_Tasks);
Elapsed := Ada.Real_Time.To_Duration (Ada.Real_Time.Clock - Start);
Ada.Text_IO.Put_Line (Item => Integer'Image (Num_Tasks) & ' ' &
Duration'Image (Elapsed) );
exit All_Calls when Num_Tasks > 2 * Num_Processors and Elapsed > Prev;
Prev := Elapsed;
Num_Tasks := Num_Tasks + 1;
end loop All_Calls;
exception -- MP_Mult_PO
when E : others =>
Ada.Text_IO.Put_Line (Item => "MP_Mult_PO " &
Ada.Exceptions.Exception_Information (E) );
end MP_Mult_PO;
^ permalink raw reply [relevance 5%]
* Re: anyone seen this link error trying to link Ada program with blas and lapack? "cannot find -lgnalasup"
@ 2010-10-16 6:25 3% ` Nasser M. Abbasi
0 siblings, 0 replies; 200+ results
From: Nasser M. Abbasi @ 2010-10-16 6:25 UTC (permalink / raw)
On 10/15/2010 10:46 PM, Nasser M. Abbasi wrote:
>
>
> Hello;
>
> I've send this email to the cygwin mailing list.
>
> I thought I check here also.
>
> I am trying to build an Ada file which has to be linked to blas and
> lapack as it uses the new Ada 2005 Solve() of linear system function.
>
> The link problem is on cygwin. I think it is a gcc installation issue
> may be.
>
> "It seems there is a library missing in the system. Did a search on
> this, but not able to find anything.
>
> $ uname -a
> CYGWIN_NT-6.1-WOW64 me-PC 1.7.7(0.230/5/3) 2010-08-31 09:58 i686 Cygwin
>
> $ gcc --version
> gcc (GCC) 4.3.4 20090804 (release) 1
>
> $ gnatmake main.adb -largs -L/usr/lib -lgnala -llapack -lblas
> gnatbind -x main.ali
> gnatlink main.ali -L/usr/lib -lgnala -llapack -lblas
> /usr/lib/gcc/i686-pc-cygwin/4.3.4/../../../../i686-pc-cygwin/bin/ld:
> cannot find -lgnalasup
> collect2: ld returned 1 exit status
> gnatlink: error when calling /usr/bin/gcc.exe
> gnatmake: *** link failed.
>
> When I copy the source file (the Ada file) to a linux system, with
> ubuntu 10.10 (linux 2.6.35-22) running gcc 4.4.5, the same command above
> works with no problem. no link error.
> "
>
> The blas and lapack libraries should come with the system normally, but
> sometime they do not. On cygwin, they are there. On Ubuntu I had to
> install them afterwords (easy with the package manager).
>
> The Ada source file is just one file. If someone wants to try the above
> gnatmake command on my file, here it is:
>
> http://12000.org/tmp/AAA/main.adb
>
> Need to use the above command to build it, which is:
>
> gnatmake main.adb -largs -L/usr/lib -lgnala -llapack -lblas
>
> It does nothing now, just wanted first to see if it builds oK.
>
> thanks
> --Nasser
I found one reference on this library, here it is
http://objectmix.com/ada/382814-gnatmake-ada-numerics-real_arrays-not-predefined-library-unit.html
"Anyway, I've started investigating the "libgnalasup" issue. This
library is referenced by i-forbla.adb, but doesn't seem to be
distributed. Replacing it with "liblapack" and "libblas" may be
enough."
But the suggestion given does not work for my on cygwin (gcc 4.3.3). I
get the same error. Using -lgnalasup or -lgnala or not using or using
gnatmake -static, nothing works.
I think now after reading the above, this is some gnat version being a
bit old on cygwin (gcc 4.3). The problem is that this is the latest
version I have of gcc on cygwin.
I now downloaded from libre site gnat 2010 GPL, on windows, and
installed it. Then did the same command above (had to add -gnat05,
becuase it now complained).
But I do not get the above error, but I do not have blas and lapack on
windows. I need to figure now where to get them for windows and where to
put them to make gnatmake happy (I think that will be
C:\GNAT\2010\LIB
(wonder why blas and lapack do not come with GNAT GPL distribution since
there are needed to link against for building the new numeric stuff?
>gnatmake main.adb -gnat05 -largs -L/usr/lib -lgnala -llapack -lblas
gnatbind -x main.ali
gnatlink main.ali -L/usr/lib -lgnala -llapack -lblas
c:/gnat/2010/bin/../libexec/gcc/i686-pc-mingw32/4.3.6/ld.exe: cannot
find -llapack
collect2: ld returned 1 exit status
gnatlink: error when calling C:\GNAT\2010\bin\gcc.exe
gnatmake: *** link failed.
--Nasser
^ permalink raw reply [relevance 3%]
* Re: basic questions on using Ada arrays
@ 2010-10-08 8:02 5% ` Alex Mentis
1 sibling, 0 replies; 200+ results
From: Alex Mentis @ 2010-10-08 8:02 UTC (permalink / raw)
On Oct 6, 6:43 pm, "Nasser M. Abbasi" <n...@12000.org> wrote:
> Ada experts:
>
> I am really rusty with Ada. Wanted to find if I apply a function to an
> array in one call without having to loop calling the function for each
> entry in the array?
>
> Suppose I have an array of values, and I want to take the sin() of each
> value in the array?
>
> This below does not work, last statement is wrong
>
> ---------------------------------------
> with ada.text_io; use ada.text_io;
> with Ada.Numerics; use Ada.Numerics;
> with Ada.Numerics.Elementary_Functions;
> use Ada.Numerics.Elementary_Functions;
> with Ada.float_Text_IO; use Ada.float_Text_IO;
>
> procedure test2 is
> nPoints : constant :=100;
> del : float := 2.0*Pi/float(nPoints-1);
> x : array(1..nPoints) of float;
> y : array(1..nPoints) of float;
> begin
>
> x(1):=0.0;
> for i in 2..nPoints loop
> x(i) := x(i-1)+del;
> end loop;
>
> x:=sin(x(1..nPoints));
>
> end test2;
> ------------------------------------
>
> Also, is there a way to initialize an array using a formula or a
> function call? I know I can do
>
> x : array(1..nPoints) of float := (others => 0.0)
>
> But I wanted to make each entry in the array to have some value
> depending on the index value. I did not know how, so that is what the
> above small loop does, to initialize x array.
>
> It would be nice to have been to do this initialization at declaration time.
>
> The bigger question really, is if one map functions on array in Ada, or
> do operations on array in one call, say like multiply a constant by
> array, without using loops all the time. loops are so out of fashion
> these days :)
>
> Something like this in Fortran
>
> ----------------------
> program main
> integer :: x(10)=1 ;
> x = 5 * x;
> end program
> -----------------------
>
> compiles, runs ok, but The Ada code
>
> ----------------------
> procedure test3 is
> x : array(1..10) of integer :=(others=>1);
> begin
> x:= 5 * x;
> end test3;
> ---------------
>
> $ gnatmake test3.adb
> test3.adb:4:12: expected type universal integer
> test3.adb:4:12: found type of x declared at line 2
>
> I undertand exactly the error and why. My question is how to code it in
> Ada to the same, without using loops?
>
> thanks,
> --Nasser
You can write your own. I'm in a hurry, so I don't have time to tweak
this the way I'd like...I'd want to try to do this with a generic
array type and with more flexible signatures for the functions/
procedures to be mapped, but my general idea is below. Putting it in
a package would be more flexible. You could probably gin up the code
to do a mapped initialization as well...but not sure. Haven't given
it much thought at the moment.
Alex
--------------------------------------------------------------------------------
-- File: Ada_Map.adb
--
-- Created on Oct 8, 2010
--------------------------------------------------------------------------------
--
-- Description of Ada_Map
--
-- @author alexander.mentis
--
with Ada.Text_IO, Ada.Numerics.Elementary_Functions;
use Ada.Text_IO, Ada.Numerics.Elementary_Functions;
procedure Ada_Map is
type Array_Type is array (1 .. 10) of Float;
function Map (F : not null access function (N : Float) return
Float;
A : Array_Type)
return Array_Type is
Result : Array_Type;
begin -- Map
for I in A'Range loop
Result (I) := F (A (I));
end loop;
return Result;
end Map;
procedure Map (P : not null access procedure (S : String);
A : Array_Type) is
begin -- Map
for I in A'Range loop
P (A (I)'Img);
end loop;
end Map;
X : Array_Type := (others => 5.0);
begin -- Ada_Map
X := Map (Sin'Access, X);
Map(Put_Line'Access, X);
end Ada_Map;
^ permalink raw reply [relevance 5%]
* Re: basic questions on using Ada arrays
@ 2010-10-08 0:04 0% ` Randy Brukardt
0 siblings, 0 replies; 200+ results
From: Randy Brukardt @ 2010-10-08 0:04 UTC (permalink / raw)
"Keith Thompson" <kst-u@mib.org> wrote in message
news:ln8w2apy0u.fsf@nuthaus.mib.org...
...
> A more "generic" solution (though it doesn't use generics) is:
If you're using an Ada 2005, this solution is better using an anonymous
access type, as in that case you can pass any matching subprogram, not just
one from the same level. (If you don't do this, this will be annoyingly hard
to use.) That is, change as follows:
> with Ada.Text_IO; use Ada.Text_IO;
> with Ada.Numerics; use Ada.Numerics;
> with Ada.Numerics.Elementary_Functions;
> use Ada.Numerics.Elementary_Functions;
> with Ada.Float_Text_IO; use Ada.Float_Text_IO;
>
> procedure Test2 is
> type Func_Ptr is access function(F: Float) return Float;
Delete this type.
> type Float_Array is array(positive range <>) of Float;
>
> function Apply(Func: Func_Ptr; Arr: Float_Array) return Float_Array is
Change this declaration to:
function Apply(Func: access function(F: Float) return Float; Arr:
Float_Array) return Float_Array is
> Result: Float_Array(Arr'Range);
> begin
> for I in Result'Range loop
> Result(I) := Func(Arr(I));
> end loop;
> return Result;
> end Apply;
>
> function Init return Float_Array is
> nPoints : constant := 100;
> del : constant Float := 2.0*Pi/Float(nPoints-1);
> Result: Float_Array(1 .. nPoints);
> begin
> for I in Result'Range loop
> Result(I) := Float(I - 1) * del;
> end loop;
> return result;
> end Init;
>
> X: constant Float_Array := Init;
> Y: constant Float_Array := Apply(sin'Access, X);
> begin
> for I in X'Range loop
> Put(X(I), Exp => 0);
> Put(" => ");
> Put(Y(I), Exp => 0);
> New_Line;
> end loop;
> end Test2;
>
> [...]
Randy.
^ permalink raw reply [relevance 0%]
Results 201-400 of ~1100 next (older) | prev (newer) | reverse | options above
-- pct% links below jump to the message on this page, permalinks otherwise --
2010-09-24 21:32 Arctan: to use with single or with double arguments? Ada novice
2010-09-24 21:55 ` Jeffrey Carter
2010-09-25 8:44 ` Ada novice
2010-09-25 17:31 ` Jeffrey Carter
2010-09-25 21:34 ` Ada novice
2010-09-26 7:31 ` Jeffrey Carter
2010-09-26 8:24 ` Ada novice
2012-02-11 0:26 ` Jack Mitchell
2012-02-11 1:11 ` Adam Beneschan
2012-02-11 8:53 ` Simon Wright
2012-02-11 10:46 ` AdaMagica
2012-02-11 15:29 ` Simon Wright
2012-02-11 16:21 ` Georg Bauhaus
2012-02-11 16:47 6% ` Simon Wright
2010-10-06 15:43 basic questions on using Ada arrays Nasser M. Abbasi
2010-10-06 16:22 ` Jacob Sparre Andersen
2010-10-07 1:55 ` Keith Thompson
2010-10-08 0:04 0% ` Randy Brukardt
2010-10-08 8:02 5% ` Alex Mentis
2010-10-16 5:46 anyone seen this link error trying to link Ada program with blas and lapack? "cannot find -lgnalasup" Nasser M. Abbasi
2010-10-16 6:25 3% ` Nasser M. Abbasi
2010-11-08 20:34 GNAT's Protected Objects Jeffrey Carter
2010-11-08 21:38 ` Anh Vo
2010-11-08 22:32 5% ` Jeffrey Carter
2010-11-09 1:50 0% ` Anh Vo
2010-12-04 6:32 5% Large arrays passed to arithmetic operators overflows GNAT stack Jerry
2010-12-04 9:19 0% ` Vinzent Hoefler
2010-12-04 14:17 0% ` Peter C. Chapin
2010-12-05 1:22 4% ` Jerry
2010-12-06 21:03 7% How to include vector operators? tolkamp
2010-12-06 21:37 5% ` Adam Beneschan
2010-12-07 11:11 0% ` tolkamp
2010-12-07 2:53 0% ` Gautier write-only
2010-12-26 10:25 5% Task execution time test Dmitry A. Kazakov
2010-12-30 8:54 5% Task execution time 2 Dmitry A. Kazakov
2010-12-30 10:43 6% Random number generation Mart van de Wege
2010-12-30 11:34 0% ` Niklas Holsti
2010-12-30 11:53 ` Georg Bauhaus
2010-12-30 12:25 ` Mart van de Wege
2010-12-30 15:29 4% ` Georg Bauhaus
2010-12-30 11:51 4% ` Brian Drummond
2010-12-30 12:16 0% ` Mart van de Wege
2010-12-30 13:04 5% ` Dmitry A. Kazakov
2011-02-03 5:52 How do I write directly to a memory address? Syntax Issues
2011-02-03 8:24 ` Ludovic Brenta
2011-02-04 9:24 ` Ludovic Brenta
2011-02-06 17:49 ` Simon Clubley
2011-02-06 18:18 ` Niklas Holsti
2011-02-06 19:05 ` Simon Clubley
2011-02-06 20:01 ` Dmitry A. Kazakov
2011-02-07 9:00 ` Ludovic Brenta
2011-02-07 13:43 5% ` Georg Bauhaus
2011-02-07 13:56 0% ` Ludovic Brenta
2011-02-07 14:58 5% ` Georg Bauhaus
2011-02-07 15:21 0% ` Dmitry A. Kazakov
2011-02-07 16:14 5% ` Robert A Duff
2011-02-07 17:23 0% ` Dmitry A. Kazakov
2011-02-07 18:38 0% ` Jeffrey Carter
2011-02-07 18:10 0% ` Georg Bauhaus
2011-02-07 19:29 0% ` Dmitry A. Kazakov
2011-02-07 16:54 0% ` Ludovic Brenta
2011-02-18 22:52 Need some light on using Ada or not Luis P. Mendes
2011-02-19 13:07 ` Brian Drummond
2011-02-19 14:36 ` Georg Bauhaus
2011-02-19 18:25 ` Brian Drummond
2011-02-20 14:34 ` Brian Drummond
2011-02-20 15:45 ` jonathan
2011-02-20 19:49 ` Pascal Obry
2011-02-20 19:57 ` Brian Drummond
2011-02-20 22:47 ` Simon Wright
2011-02-21 12:52 ` Brian Drummond
2011-02-22 2:15 3% ` Shark8
2011-02-21 18:43 Ann: Mathpaqs, release Feb. 2011 Gautier write-only
2011-02-21 23:59 6% ` Nasser M. Abbasi
2011-03-17 13:33 6% Error in gnat-4.6 (opensuse 11.4) ? reinkor
2011-03-17 14:31 Help with low level Ada Syntax Issues
2011-03-17 17:55 4% ` Jeffrey Carter
2011-03-17 19:30 0% ` Syntax Issues
2011-03-27 1:31 on using array index, vectorized operation Nasser M. Abbasi
2011-03-27 20:01 ` Cyrille
2011-03-27 20:44 ` Nasser M. Abbasi
2011-03-27 22:09 ` Phil Clayton
2011-03-27 22:23 ` Nasser M. Abbasi
2011-03-29 2:50 6% ` Randy Brukardt
2011-03-29 4:55 0% ` Nasser M. Abbasi
2011-04-20 10:39 If not Ada, what else Alex R. Mosteo
2015-07-09 21:15 ` Bob Duff
2015-07-09 22:23 ` David Botton
2015-07-09 22:39 ` Paul Rubin
2015-07-10 0:20 ` David Botton
2015-07-10 4:26 ` Paul Rubin
2015-07-10 15:01 ` David Botton
2015-07-10 18:22 ` Paul Rubin
2015-07-10 19:10 ` David Botton
2015-07-10 19:43 ` Patrick Noffke
2015-07-11 10:46 ` Brian Drummond
2015-07-13 14:02 ` Patrick Noffke
2015-07-13 14:16 ` David Botton
2015-07-16 20:19 ` Serge Robyns
2015-07-17 1:50 ` David Botton
2015-07-21 6:30 ` Gour
2015-07-21 16:24 ` David Botton
2015-07-21 17:29 ` Niklas Holsti
2015-07-21 18:51 ` Simon Wright
2015-07-21 19:36 ` David Botton
2015-07-22 12:00 ` Jean François Martinez
2015-07-27 22:59 ` Randy Brukardt
2015-07-29 12:38 ` EGarrulo
2015-07-30 10:59 5% ` darkestkhan
2011-05-13 16:05 4% Newbie question: Binary operator expected? Geoffrey Laval
2011-05-13 17:14 0% ` Adam Beneschan
2011-05-27 20:50 Interfacing Ada multidimensional arrays with Fortran David Sauvage
2011-05-28 9:41 6% ` Simon Wright
2011-05-28 16:45 ` Simon Wright
2011-06-09 7:55 5% ` David Sauvage
2011-06-14 21:12 5% I need feedback juanmiuk
2011-06-14 21:50 ` Ludovic Brenta
2011-06-15 11:40 ` Yannick Duchêne (Hibou57)
2011-06-15 19:38 ` Shark8
2011-06-16 4:24 5% ` juanmiuk
2011-06-16 7:34 0% ` Ludovic Brenta
2011-07-18 8:47 6% Incorrect error? ldries46
2011-07-18 9:45 4% ` stefan-lucks
2011-07-18 10:40 0% ` AdaMagica
2011-07-18 12:39 0% ` Dmitry A. Kazakov
2011-07-18 12:45 4% ` stefan-lucks
2011-07-18 10:39 6% ` Nicholas Collin Paul de Glouceſter
2011-07-18 15:58 0% ` Adam Beneschan
2011-07-25 17:36 7% Eigenvalues to find roots of polynomials marius63
2011-07-26 6:21 ` John B. Matthews
2011-07-26 15:40 7% ` marius63
2011-09-29 10:25 5% fixed point vs floating point RasikaSrinivasan@gmail.com
2011-09-30 10:17 ` Stephen Leake
2011-10-01 13:37 4% ` RasikaSrinivasan@gmail.com
2011-10-12 20:48 sharp ß and ss in Ada keywords like ACCESS Dmitry A. Kazakov
2011-10-12 22:56 ` sharp ß and ss in Ada keywords like AC CESS Georg Bauhaus
2011-10-13 8:10 ` Dmitry A. Kazakov
2011-10-13 12:13 ` Georg Bauhaus
2011-10-13 13:25 3% ` Dmitry A. Kazakov
2011-10-12 23:38 organizing deep source trees with child packages Greg Moncreaff
2011-10-13 8:20 ` Stephen Leake
2011-10-13 13:19 ` Greg Moncreaff
2011-10-13 14:18 ` Ludovic Brenta
2011-10-13 22:25 ` Yannick Duchêne (Hibou57)
2011-10-14 7:27 ` Dmitry A. Kazakov
2011-10-16 12:51 ` Stephen Leake
2011-10-16 13:43 ` Dmitry A. Kazakov
2011-10-18 11:12 ` Stephen Leake
2011-10-18 13:07 ` Dmitry A. Kazakov
2011-10-19 1:51 ` Stephen Leake
2011-10-19 9:03 3% ` Dmitry A. Kazakov
2011-10-19 9:52 0% ` Ludovic Brenta
2011-10-20 10:50 0% ` Stephen Leake
2011-11-08 10:05 Iterators in Ada2012 comp.lang.php
2011-11-08 13:13 ` Georg Bauhaus
2011-11-09 4:12 ` R. Tyler Croy
2011-11-09 10:55 4% ` Georg Bauhaus
2011-11-25 14:20 0% ` Yannick Duchêne (Hibou57)
2011-12-21 1:08 Basic question on Ada multi-dimensional arrays, are they true (contiguous) arrays? aliasing rules? Nasser M. Abbasi
2011-12-21 21:11 4% ` Adrian-Ken Rueegsegger
2011-12-21 21:13 4% ` Adrian-Ken Rueegsegger
2012-04-25 7:47 What would you like in Ada202X? Martin
2012-05-06 18:48 ` Niklas Holsti
2012-07-03 15:41 ` Pascal Obry
2012-07-03 15:50 ` Pascal Obry
2012-07-04 11:41 ` Ada novice
2012-07-04 12:30 ` Nasser M. Abbasi
2012-07-04 17:55 5% ` Simon Wright
2012-07-04 18:35 0% ` Nasser M. Abbasi
2012-06-11 21:55 Practicalities of Ada for app development Adam Beneschan
2012-06-12 21:12 ` Nomen Nescio
2012-06-13 0:04 4% ` Adam Beneschan
2012-06-13 3:04 0% ` Shark8
2012-06-13 8:37 0% ` Georg Bauhaus
2012-06-20 10:09 5% a bug in code shown in ada2012 rational or is it me? Nasser M. Abbasi
2012-06-23 12:02 5% questions on using the array component iterator for 2012 Nasser M. Abbasi
2012-06-23 12:04 0% ` Nasser M. Abbasi
2012-06-24 8:05 5% Any easy/build-in construct to extract submatrices from larger matrix? Nasser M. Abbasi
2012-06-26 13:47 6% how to print an array range? Nasser M. Abbasi
2012-06-26 13:54 ` Georg Bauhaus
2012-06-26 14:08 6% ` Nasser M. Abbasi
2012-06-26 14:24 6% ` Nasser M. Abbasi
2012-06-28 6:59 0% ` Shark8
2012-06-26 15:49 6% Why this error, value not in range of subtype of "Standard.Integer"? Nasser M. Abbasi
2012-06-26 17:20 0% ` Adam Beneschan
2012-06-26 18:00 4% ` Niklas Holsti
2012-06-26 21:39 0% ` Robert A Duff
2012-06-30 2:40 6% Reason for elements of 'ada.numerics.generic_real_arrays' real_vector and real_matrix types not being aliased ? rodakay
2012-07-01 5:53 GNAT and Dimension Checking AdaMagica
2012-07-06 10:47 2% ` AdaMagica
2012-07-06 18:38 Free AMD Core Math Library (BLAS/LAPACK) + Ada Ada novice
2012-07-07 13:37 ` Charly
2012-07-07 14:01 ` Ada novice
2012-07-08 6:31 ` Charly
2012-07-08 12:22 ` Ada novice
2012-07-09 18:30 ` Charly
2012-07-09 21:15 ` Ada novice
2012-07-09 21:36 ` Nasser M. Abbasi
2012-07-10 5:03 ` Ada novice
2012-07-10 9:35 ` Brian Drummond
2012-07-10 9:51 ` Nasser M. Abbasi
2012-07-10 12:29 ` Ada novice
2012-07-10 20:02 ` Ada novice
2012-07-11 7:49 ` Simon Wright
2012-07-11 9:47 5% ` Ken Thomas
2012-07-11 19:30 0% ` Simon Wright
2012-07-08 0:08 How to initialize a matrix of one column only? Nasser M. Abbasi
2012-07-08 22:56 ` Jerry
2012-07-09 9:35 5% ` Simon Wright
2012-07-12 4:13 0% ` Jerry
2012-07-09 23:27 Does Ada need elemental functions to make it suitable for scientific work? Nasser M. Abbasi
2012-07-10 4:24 ` gautier_niouzes
2012-07-10 5:22 ` Ada novice
[not found] ` <637de084-0e71-4077-a1c5-fc4200cad3cf@googlegroups.com>
2012-07-10 8:39 5% ` Nasser M. Abbasi
2012-07-12 0:22 0% ` robin.vowels
2012-07-20 1:51 0% ` Randy Brukardt
2012-07-10 12:46 5% ` Brian Drummond
2012-07-12 0:38 7% Lapack Ada binding matrices/vectors issue, how to best to resolve? Nasser M. Abbasi
2012-07-12 0:45 0% ` Nasser M. Abbasi
2012-07-14 21:13 Pre-Ada95 books still worth reading wrp
2012-07-15 7:18 ` J-P. Rosen
[not found] ` <67e508lh89b705q2d0u82in99p6u15cel9@invalid.netcom.com>
2012-07-15 13:33 ` Ada novice
2012-07-15 20:09 4% ` wrp
2012-07-15 18:40 Efficient Sequential Access to Arrays Keean Schupke
2012-07-15 19:48 ` Dmitry A. Kazakov
2012-07-15 20:03 ` Keean Schupke
2012-07-15 21:44 5% ` Georg Bauhaus
2012-08-06 16:45 Ada.Locales pseudo-string types Marius Amado-Alves
2012-08-06 17:10 ` Marius Amado-Alves
2012-08-06 19:15 ` J-P. Rosen
2012-08-06 19:34 ` Simon Wright
2012-08-06 20:07 ` Marius Amado-Alves
2012-08-06 20:57 ` Simon Wright
2012-08-06 21:09 ` Vasiliy Molostov
2012-08-06 23:07 ` Adam Beneschan
2012-08-07 8:44 ` Marius Amado-Alves
2012-08-07 13:14 ` Marius Amado-Alves
2012-08-07 15:42 ` Adam Beneschan
2012-08-07 18:22 ` Marius Amado-Alves
2012-08-07 20:10 ` Adam Beneschan
2012-08-07 20:42 ` Marius Amado-Alves
2012-08-08 7:04 ` Niklas Holsti
2012-08-08 7:18 ` Dmitry A. Kazakov
2012-08-08 7:37 ` Niklas Holsti
2012-08-08 8:28 ` J-P. Rosen
2012-08-08 11:35 ` Niklas Holsti
2012-08-08 14:05 5% ` Georg Bauhaus
2012-08-15 6:16 ada lapack Leo Brewin
2012-08-17 6:25 ` Ada novice
2012-08-17 7:11 ` Leo Brewin
2012-08-17 7:42 ` Ada novice
2012-08-17 9:43 ` Niklas Holsti
2012-08-17 10:27 ` Ada novice
2012-08-17 11:08 ` Niklas Holsti
2012-08-17 11:33 ` Ada novice
2012-08-17 13:45 ` Leo Brewin
2012-08-17 14:11 ` Marc C
2012-08-18 11:57 ` Ada novice
2012-08-18 13:13 5% ` Niklas Holsti
2012-08-18 13:48 5% ` Ada novice
2012-08-18 15:22 5% ` Nasser M. Abbasi
2012-08-18 16:33 5% ` Ada novice
2012-08-18 17:32 7% ` Simon Wright
2012-08-18 20:45 0% ` Niklas Holsti
2012-08-30 22:33 Question: re Image Files Austin Obyrne
2012-08-31 7:18 ` Mark Murray
2012-08-31 9:14 ` Austin Obyrne
2012-08-31 17:09 ` Mark Murray
2012-08-31 17:36 ` Austin Obyrne
2012-08-31 22:09 5% ` Shark8
2012-09-17 13:37 6% problem with Real_Matrix*Real_Matrix reinkor
2012-09-17 17:01 0% ` Niklas Holsti
2012-09-29 17:34 highest bit, statically determined Georg Bauhaus
2012-09-30 15:39 6% ` Anatoly Chernyshev
2012-09-30 18:36 0% ` Shark8
2012-10-01 8:07 0% ` Georg Bauhaus
2012-10-21 0:37 11% Is this a bug in Ada.Numerics? Leo Brewin
2012-10-21 1:54 5% ` Yannick Duchêne (Hibou57)
2012-10-21 2:39 6% ` Leo Brewin
2012-10-21 1:55 11% ` Ludovic Brenta
2012-10-21 2:32 12% ` Leo Brewin
2012-10-21 3:39 6% ` Ludovic Brenta
2012-10-21 3:54 6% ` Leo Brewin
2012-10-21 8:59 6% ` Georg Bauhaus
2012-10-23 15:48 6% ` Vincent Marciante
2012-10-23 22:52 12% ` Leo Brewin
2012-10-23 23:09 6% ` Jeffrey Carter
2012-10-26 22:45 pragma import (C, , ); -- import a constant value from C library Enzo Guerra
2012-10-27 7:40 7% ` Dmitry A. Kazakov
2012-10-27 8:15 5% ` Simon Wright
2012-10-27 8:19 0% ` Simon Wright
2012-10-27 8:47 0% ` Dmitry A. Kazakov
2012-12-18 7:45 Press Release - Ada 2012 Language Standard Approved by ISO Dirk Craeynest
2012-12-18 16:57 ` Robert A Duff
2012-12-18 21:12 ` Bill Findlay
2012-12-19 8:33 5% ` Dmitry A. Kazakov
2012-12-19 9:00 0% ` Georg Bauhaus
2012-12-19 9:19 0% ` Dmitry A. Kazakov
2012-12-19 14:34 0% ` Bill Findlay
2012-12-20 1:52 0% ` Randy Brukardt
2012-12-21 9:01 0% ` Dmitry A. Kazakov
2012-12-23 22:28 6% X : Real_Vector := Solve(A => A, X => B); -- Why X as argument name? Gustaf Thorslund
2012-12-24 8:33 4% ` Niklas Holsti
2012-12-24 11:50 0% ` Simon Wright
2012-12-24 12:58 0% ` Niklas Holsti
2012-12-24 21:25 0% ` Gustaf Thorslund
2012-12-24 20:42 0% ` Gustaf Thorslund
2012-12-24 20:10 0% ` jpwoodruff
2012-12-27 18:48 5% A thicker binding for Lapack jpwoodruff
2012-12-27 19:18 ` Shark8
2012-12-29 18:36 ` jpwoodruff
2012-12-29 19:59 6% ` Simon Wright
2013-01-06 0:46 5% Announce: Updated version of ada-lapack on sourceforge Leo Brewin
2013-01-07 21:57 0% ` Jerry
2013-02-25 10:20 Parallel_Simulation Vincent LAFAGE
2013-02-25 12:40 5% ` Parallel_Simulation John B. Matthews
2013-02-25 17:17 0% ` Parallel_Simulation Vincent LAFAGE
2013-02-25 18:30 0% ` Parallel_Simulation John B. Matthews
2013-02-26 7:13 0% ` Parallel_Simulation Vincent LAFAGE
2013-02-26 7:09 0% ` Parallel_Simulation Vincent LAFAGE
2013-03-11 19:42 Is this expected behavior or not Anh Vo
2013-03-12 9:27 ` Dmitry A. Kazakov
2013-03-12 17:19 ` Robert A Duff
2013-03-12 17:42 ` Dmitry A. Kazakov
2013-03-12 18:04 ` Georg Bauhaus
2013-03-12 18:21 ` Dmitry A. Kazakov
2013-03-12 22:23 ` Georg Bauhaus
2013-03-13 8:49 ` Dmitry A. Kazakov
2013-03-13 9:45 ` J-P. Rosen
2013-03-13 13:31 ` Dmitry A. Kazakov
2013-03-13 14:34 ` Georg Bauhaus
2013-03-13 17:05 ` Shark8
2013-03-13 17:45 ` Simon Wright
2013-03-13 19:37 ` Dmitry A. Kazakov
2013-03-13 21:09 ` Randy Brukardt
2013-03-13 22:48 ` Shark8
2013-03-14 22:01 ` Randy Brukardt
2013-03-15 3:27 ` Shark8
2013-03-15 21:05 ` Randy Brukardt
2013-03-15 21:46 ` Robert A Duff
2013-03-16 5:52 ` Shark8
2013-03-16 7:41 ` Dmitry A. Kazakov
2013-03-16 16:55 5% ` Shark8
2013-03-29 0:32 5% Pure vs. Pure; aspect vs. pragma Shark8
2013-04-22 18:27 5% Interresting difference in Normal-Returns/Expression-Functions and Extended-Returns Shark8
2013-04-28 5:14 Seeking for papers about tagged types vs access to subprograms Yannick Duchêne (Hibou57)
2013-05-08 8:23 ` Dmitry A. Kazakov
2013-05-08 9:39 ` Yannick Duchêne (Hibou57)
2013-05-08 10:23 ` Dmitry A. Kazakov
2013-05-08 11:08 ` Yannick Duchêne (Hibou57)
2013-05-08 15:29 ` Dmitry A. Kazakov
2013-05-08 20:27 ` Randy Brukardt
2013-05-09 7:33 ` Dmitry A. Kazakov
2013-05-09 22:19 ` Randy Brukardt
2013-05-10 7:48 ` Dmitry A. Kazakov
2013-05-11 0:42 ` Randy Brukardt
2013-05-11 6:37 ` Dmitry A. Kazakov
2013-05-11 7:06 ` Georg Bauhaus
2013-05-11 7:42 ` Dmitry A. Kazakov
2013-05-14 2:29 ` Randy Brukardt
2013-05-14 7:44 ` Dmitry A. Kazakov
2013-05-14 11:34 ` Yannick Duchêne (Hibou57)
2013-05-14 12:16 ` Dmitry A. Kazakov
2013-05-15 11:20 ` Peter C. Chapin
2013-05-15 13:00 ` Dmitry A. Kazakov
2013-05-15 21:12 ` Peter C. Chapin
2013-05-15 22:08 4% ` Dmitry A. Kazakov
2013-05-16 11:31 0% ` Peter C. Chapin
2013-05-16 12:20 4% ` Dmitry A. Kazakov
2013-05-16 13:10 0% ` Peter C. Chapin
2013-05-16 13:54 4% ` Dmitry A. Kazakov
2013-07-08 17:56 The future of Spark . Spark 2014 : a wreckage vincent.diemunsch
2013-07-08 21:32 ` Randy Brukardt
2013-07-09 7:28 ` Dmitry A. Kazakov
2013-07-09 20:37 ` Randy Brukardt
2013-07-10 10:03 ` Dmitry A. Kazakov
2013-07-10 23:21 ` Randy Brukardt
2013-07-12 1:01 5% ` Slow? Ada?? Bill Findlay
2013-07-13 0:52 7% GNAT does not consistently raise an exception to log(0.0) Jerry
2013-07-13 7:26 6% ` Dmitry A. Kazakov
2013-07-14 3:51 0% ` Jerry
2013-07-13 7:34 0% ` Simon Wright
2013-07-14 3:42 6% ` Jerry
2013-07-13 9:37 0% ` AdaMagica
2013-07-14 3:44 0% ` Jerry
2013-07-19 19:28 “A Comparison of Four Pseudo Random Number Generators Implemented in Ada” Yannick Duchêne (Hibou57)
2013-07-19 22:07 5% ` ³A Comparison of Four Pseudo Random Number Generators Implemented in Ada² Bill Findlay
2013-07-20 0:18 0% ` Jeffrey Carter
2013-07-20 0:41 0% ` Yannick Duchêne (Hibou57)
2013-09-19 0:17 4% How to include shared code Emanuel Berg
2013-09-19 7:20 0% ` Dmitry A. Kazakov
2013-11-12 11:09 Increasing GNAT's heap Dmitry A. Kazakov
2013-11-12 13:26 ` Georg Bauhaus
2013-11-12 14:00 ` Dmitry A. Kazakov
2013-11-12 19:30 7% ` Georg Bauhaus
2014-04-07 14:34 Statistics Poul-Erik Andreasen
2014-04-08 21:34 ` Statistics gautier_niouzes
2014-04-09 0:24 5% ` Statistics Poul-Erik Andreasen
2014-04-09 6:37 0% ` Statistics Simon Wright
2014-04-09 7:58 ` Statistics J-P. Rosen
2014-04-09 9:52 5% ` Statistics Simon Wright
2014-04-09 21:58 0% ` Statistics Poul-Erik Andreasen
2014-06-05 17:49 OT: A bit of Sudoku Mike H
2014-06-05 18:30 ` Adam Beneschan
2014-06-05 19:00 ` J-P. Rosen
2014-06-05 23:12 ` Robert A Duff
2014-06-05 23:39 ` Adam Beneschan
2014-06-06 14:13 2% ` Brad Moore
2014-06-15 17:07 Lotto simulation montgrimpulo
2014-06-15 18:54 4% ` Stefan.Lucks
2014-06-15 19:53 ` J-P. Rosen
2014-06-16 5:25 ` Stefan.Lucks
2014-06-16 7:49 ` J-P. Rosen
2014-06-16 11:15 5% ` Stefan.Lucks
2014-06-15 20:10 ` Dirk Heinrichs
2014-06-15 20:43 5% ` Simon Wright
2014-06-16 20:22 0% ` Dirk Heinrichs
2014-06-16 8:03 6% Lotto simulation 2 montgrimpulo
2014-06-16 12:21 5% ` Stefan.Lucks
2014-07-04 17:23 Benchmark Ada, please Victor Porton
2014-07-05 12:34 4% ` Guillaume Foliard
2014-10-01 1:49 casting types Stribor40
2014-10-01 2:06 ` Jeffrey Carter
2014-10-01 2:56 ` Stribor40
2014-10-02 9:24 ` Brian Drummond
2014-10-03 3:35 ` Stribor40
2014-10-03 8:29 ` Jacob Sparre Andersen
2014-10-06 23:36 4% ` brbarkstrom
2014-10-03 23:29 array of string Stribor40
2014-10-07 16:49 6% ` brbarkstrom
2014-10-16 12:55 5% Gnat Pro Cross compiling Nahro Nadir
2014-11-19 2:51 how to analyze clock drift Emanuel Berg
2014-11-19 9:01 ` Dmitry A. Kazakov
2014-11-19 22:12 ` Emanuel Berg
2014-11-20 9:42 ` Dmitry A. Kazakov
2014-11-20 20:41 ` Emanuel Berg
2014-11-20 21:27 ` Dmitry A. Kazakov
2014-11-20 21:54 ` Emanuel Berg
2014-11-21 2:27 ` Dennis Lee Bieber
2014-11-21 3:02 ` Emanuel Berg
2014-11-21 16:49 ` Dennis Lee Bieber
2014-11-21 21:06 ` Emanuel Berg
2014-11-22 18:18 ` Dennis Lee Bieber
2014-11-23 20:15 ` Emanuel Berg
2014-11-24 1:15 3% ` Dennis Lee Bieber
2014-11-21 11:41 How to get nice with GNAT? Natasha Kerensikova
2014-11-23 17:41 ` brbarkstrom
2014-11-23 20:49 ` Jeffrey Carter
2014-11-24 3:05 4% ` brbarkstrom
2014-12-22 16:22 {Pre,Post}conditions and side effects Jean François Martinez
2014-12-22 17:18 ` Brad Moore
2014-12-23 8:22 ` Jean François Martinez
2014-12-23 17:05 ` Robert A Duff
2014-12-23 21:09 ` Jean François Martinez
2014-12-23 23:02 ` Peter Chapin
2014-12-24 1:03 ` Robert A Duff
2015-04-24 8:59 4% ` Jacob Sparre Andersen
2015-04-24 22:26 0% ` Peter Chapin
2015-04-25 0:13 0% ` Randy Brukardt
2015-04-25 0:31 0% ` Bob Duff
2015-06-28 14:06 How to shuffle/jumble letters of a given word? Trish Cayetano
2015-06-28 21:07 4% ` Simon Wright
2015-06-28 21:23 ` Jeffrey R. Carter
2015-06-29 8:05 5% ` Simon Wright
2015-06-29 8:13 0% ` Dmitry A. Kazakov
2015-06-29 21:45 6% ` MM
2015-07-17 15:47 Error "exception not permitted here" when putting EXCEPTION in a loop Trish Cayetano
2015-07-17 15:58 ` G.B.
2015-07-18 8:14 3% ` Trish Cayetano
2015-07-18 10:08 ` Björn Lundin
2015-07-18 12:41 4% ` Trish Cayetano
2015-07-18 13:56 ` Björn Lundin
2015-07-18 14:32 4% ` Trish Cayetano
2015-07-18 14:59 4% ` Björn Lundin
2015-11-03 0:45 7% Understanding generic package functions Nick Gordon
2015-11-03 3:36 7% ` Jeffrey R. Carter
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox