* basic questions on using Ada arrays
@ 2010-10-06 15:43 Nasser M. Abbasi
2010-10-06 16:17 ` Pascal Obry
` (4 more replies)
0 siblings, 5 replies; 11+ messages in thread
From: Nasser M. Abbasi @ 2010-10-06 15:43 UTC (permalink / raw)
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
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: basic questions on using Ada arrays
2010-10-06 15:43 basic questions on using Ada arrays Nasser M. Abbasi
@ 2010-10-06 16:17 ` Pascal Obry
2010-10-06 16:22 ` Jacob Sparre Andersen
` (3 subsequent siblings)
4 siblings, 0 replies; 11+ messages in thread
From: Pascal Obry @ 2010-10-06 16:17 UTC (permalink / raw)
Le 06/10/2010 17:43, Nasser M. Abbasi a �crit :
> 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?
Ada does not support this.
Pascal.
--
--|------------------------------------------------------
--| Pascal Obry Team-Ada Member
--| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE
--|------------------------------------------------------
--| http://www.obry.net - http://v2p.fr.eu.org
--| "The best way to travel is by means of imagination"
--|
--| gpg --keyserver keys.gnupg.net --recv-key F949BD3B
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: basic questions on using Ada arrays
2010-10-06 15:43 basic questions on using Ada arrays Nasser M. Abbasi
2010-10-06 16:17 ` Pascal Obry
@ 2010-10-06 16:22 ` Jacob Sparre Andersen
2010-10-07 1:55 ` Keith Thompson
2010-10-06 17:03 ` Jeffrey Carter
` (2 subsequent siblings)
4 siblings, 1 reply; 11+ messages in thread
From: Jacob Sparre Andersen @ 2010-10-06 16:22 UTC (permalink / raw)
Nasser M. Abbasi wrote:
> 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?
Only if the function/operation is declared for the array type.
The operator "and" is automatically declared for arrays of Booleans.
> Suppose I have an array of values, and I want to take the sin() of
> each value in the array?
The function "Sin" is not declared automatically for arrays of Floats.
You will have to declare it yourself:
function Sin (Item : in The_Array_Type) return The_Array_Type is
begin
return Result : The_Array_Type do
for I in Item'Range loop
Result (I) := Sin (Item (I));
end loop;
end return;
end Sin;
> But I wanted to make each entry in the array to have some value
> depending on the index value.
You have to use a loop to do that (you may of course hide the loop in a
function).
> 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 :)
There are generally no predefined mathematical operations on arrays of
scalars in Ada. You could propose it to the ARG. They might even
accept it.
> 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;
> ---------------
... should be:
procedure Test_3 is
type Demo_Array is array (1 .. 10) of Integer;
function "*" (Left : Integer; Right : Demo_Array)
return Demo_Array is
begin
return Result : Demo_Array do
for I in Right'Range loop
Result (I) := Left * Right (I);
end loop;
end return;
end "*";
X : Demo_Array := (others => 1);
begin
X := 5 * X;
end Test_3;
Jacob
--
Jacob Sparre Andersen Research & Innovation
Vesterbrogade 148K, 1. th.
1620 K�benhavn V
Danmark
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: basic questions on using Ada arrays
2010-10-06 15:43 basic questions on using Ada arrays Nasser M. Abbasi
2010-10-06 16:17 ` Pascal Obry
2010-10-06 16:22 ` Jacob Sparre Andersen
@ 2010-10-06 17:03 ` Jeffrey Carter
2010-10-06 19:54 ` Simon Wright
2010-10-08 8:02 ` Alex Mentis
4 siblings, 0 replies; 11+ messages in thread
From: Jeffrey Carter @ 2010-10-06 17:03 UTC (permalink / raw)
On 10/06/2010 08:43 AM, Nasser M. Abbasi wrote:
>
> 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.
Certainly, but one must use a named array type, not anonymous types as you have
done.
You can find examples of such functions in Ada.Strings.Fixed (ARM A.4.3). Type
String is simply an array type. For example
X : String := 5 * 'x';
results is X having the subtype String (1 .. 5) and the value "xxxxx". This
doesn't give a different value for each component, but it's easy enough to write
one yourself:
function Digit_List (Length : in Natural) return String;
-- Returns a value of subtype String (1 .. Length) containing repeated
-- sequences of "1234567890". Each position contains the value of its
-- index modulo 10.
function Digit_List (Length : in Natural) return String is
function Last_Digit (Value : in Positive) return Character;
-- returns the Character representation of the last digit in the
-- base 10 image of Value.
function Last_Digit (Value : in Positive) return Character is
Image : constant String := Integer'Image (Value);
begin -- Last_Digit
return Image (Image'Last);
end Last_Digit;
Result : String (1 .. Length);
begin -- Digit_List
All_Digits : for I in Result'range loop
Result (I) := Last_Digit (I);
end loop All_Digits;
return Result;
end Digit_List;
Column_Header : constant String := Digit_List (80);
Of course, all of this requires you to write loops. Loops may be "out of
fashion", but Ada isn't about following fashion; if it were, it would look like
C, not have all those inefficient run-time checks, and give far fewer
compilation errors.
--
Jeff Carter
"Don't knock masturbation. It's sex with someone I love."
Annie Hall
45
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: basic questions on using Ada arrays
2010-10-06 15:43 basic questions on using Ada arrays Nasser M. Abbasi
` (2 preceding siblings ...)
2010-10-06 17:03 ` Jeffrey Carter
@ 2010-10-06 19:54 ` Simon Wright
2010-10-08 8:02 ` Alex Mentis
4 siblings, 0 replies; 11+ messages in thread
From: Simon Wright @ 2010-10-06 19:54 UTC (permalink / raw)
"Nasser M. Abbasi" <nma@12000.org> writes:
> 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?
This is probably GNAT-only, and may result in compilation warnings about
use of implementation-specific packages, but in recent GNATs there's a
package System.Generic_Array_Operations containing
generic
type X_Scalar is private;
type Result_Scalar is private;
type X_Vector is array (Integer range <>) of X_Scalar;
type Result_Vector is array (Integer range <>) of Result_Scalar;
with function Operation (X : X_Scalar) return Result_Scalar;
function Vector_Elementwise_Operation (X : X_Vector) return Result_Vector;
which you'd instantiate something like
type Vector is array (Positive range <>) of Float;
function Sin
is new System.Generic_Array_Operations.Vector_Elementwise_Operation
(X_Scalar => Float,
Result_Scalar => Float,
X_Vector => Vector,
Result_Vector => Vector,
Operation => Ada.Numerics.Elementary_Functions.Sin);
V : Vector;
begin
-- Set up V
V := Sin (V);
(NOT COMPILED!)
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: basic questions on using Ada arrays
2010-10-06 16:22 ` Jacob Sparre Andersen
@ 2010-10-07 1:55 ` Keith Thompson
2010-10-08 0:04 ` Randy Brukardt
0 siblings, 1 reply; 11+ messages in thread
From: Keith Thompson @ 2010-10-07 1:55 UTC (permalink / raw)
Jacob Sparre Andersen <sparre@nbi.dk> writes:
> Nasser M. Abbasi wrote:
>
>> 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?
>
> Only if the function/operation is declared for the array type.
>
> The operator "and" is automatically declared for arrays of Booleans.
>
>> Suppose I have an array of values, and I want to take the sin() of
>> each value in the array?
>
> The function "Sin" is not declared automatically for arrays of Floats.
> You will have to declare it yourself:
>
> function Sin (Item : in The_Array_Type) return The_Array_Type is
> begin
> return Result : The_Array_Type do
> for I in Item'Range loop
> Result (I) := Sin (Item (I));
> end loop;
> end return;
> end Sin;
A more "generic" solution (though it doesn't use generics) is:
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;
type Float_Array is array(positive range <>) of Float;
function Apply(Func: Func_Ptr; 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;
[...]
Note that the initialization function multiplies by "del" for each entry
rather than adding "del"; the latter can cause cumulative errors.
For numeric work, consider using Long_Float rather than Float; it's more
precise (well, at least as precise) and very often no more expensive.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: basic questions on using Ada arrays
2010-10-07 1:55 ` Keith Thompson
@ 2010-10-08 0:04 ` Randy Brukardt
2010-10-08 14:47 ` Jacob Sparre Andersen
0 siblings, 1 reply; 11+ messages in thread
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 [flat|nested] 11+ messages in thread
* Re: basic questions on using Ada arrays
2010-10-06 15:43 basic questions on using Ada arrays Nasser M. Abbasi
` (3 preceding siblings ...)
2010-10-06 19:54 ` Simon Wright
@ 2010-10-08 8:02 ` Alex Mentis
4 siblings, 0 replies; 11+ messages in thread
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 [flat|nested] 11+ messages in thread
* Re: basic questions on using Ada arrays
2010-10-08 0:04 ` Randy Brukardt
@ 2010-10-08 14:47 ` Jacob Sparre Andersen
2010-10-09 6:35 ` Randy Brukardt
0 siblings, 1 reply; 11+ messages in thread
From: Jacob Sparre Andersen @ 2010-10-08 14:47 UTC (permalink / raw)
Randy Brukardt wrote;
> If you're using an Ada 2005, [...]
> 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;
Wouldn't this implementation of the function be more elegant?
function Apply (Func : access function (F : Float) return Float;
Arr : in Float_Array) return Float_Array is
begin
return Result : Float_Array (Arr'Range) do
Result (I) := Func (Arr (I));
end return;
end Apply;
Greetings,
Jacob
--
Adlai Stevenson said it all when, at an event during the
1956 Presidential campaign, a woman shouted, "You have the
vote of every thinking person!" Stevenson shouted back,
"That's not enough, madam, we need a majority!"
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: basic questions on using Ada arrays
2010-10-08 14:47 ` Jacob Sparre Andersen
@ 2010-10-09 6:35 ` Randy Brukardt
2010-10-26 2:20 ` Yannick Duchêne (Hibou57)
0 siblings, 1 reply; 11+ messages in thread
From: Randy Brukardt @ 2010-10-09 6:35 UTC (permalink / raw)
"Jacob Sparre Andersen" <sparre@nbi.dk> wrote in message
news:871v80g2s7.fsf@hugsarin.sparre-andersen.dk...
> Randy Brukardt wrote;
>
>> If you're using an Ada 2005, [...]
>
...
> Wouldn't this implementation of the function be more elegant?
>
> function Apply (Func : access function (F : Float) return Float;
> Arr : in Float_Array) return Float_Array is
> begin
> return Result : Float_Array (Arr'Range) do
> Result (I) := Func (Arr (I));
> end return;
> end Apply;
It's too elegant: you forgot the for loop! (Thus, there is no declaration
for I). It should be:
function Apply (Func : access function (F : Float) return Float;
Arr : in Float_Array) return Float_Array is
begin
return Result : Float_Array (Arr'Range) do
for I in Arr'Range loop
Result (I) := Func (Arr (I));
end loop;
end return;
end Apply;
Using the extended return does simplify the code and possibly improves the
performance as well (by eliminating a copy of the array).
Randy.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: basic questions on using Ada arrays
2010-10-09 6:35 ` Randy Brukardt
@ 2010-10-26 2:20 ` Yannick Duchêne (Hibou57)
0 siblings, 0 replies; 11+ messages in thread
From: Yannick Duchêne (Hibou57) @ 2010-10-26 2:20 UTC (permalink / raw)
Le Sat, 09 Oct 2010 08:35:37 +0200, Randy Brukardt <randy@rrsoftware.com>
a écrit:
> Using the extended return does simplify the code and possibly improves
> the
> performance as well (by eliminating a copy of the array).
Already discussed last year. This may be an optimization hint for some
compilers, as other compilers may apply the same optimization even in the
lack of this extended return statement (it is related to avoiding copy,
but this semantic formally apply to limited type only). This is compiler
specific, unless Ada 2012 changed this to make it the standard semantic.
--
Si les chats miaulent et font autant de vocalises bizarres, c’est pas pour
les chiens.
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2010-10-26 2:20 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-10-06 15:43 basic questions on using Ada arrays Nasser M. Abbasi
2010-10-06 16:17 ` Pascal Obry
2010-10-06 16:22 ` Jacob Sparre Andersen
2010-10-07 1:55 ` Keith Thompson
2010-10-08 0:04 ` Randy Brukardt
2010-10-08 14:47 ` Jacob Sparre Andersen
2010-10-09 6:35 ` Randy Brukardt
2010-10-26 2:20 ` Yannick Duchêne (Hibou57)
2010-10-06 17:03 ` Jeffrey Carter
2010-10-06 19:54 ` Simon Wright
2010-10-08 8:02 ` Alex Mentis
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox