comp.lang.ada
 help / color / mirror / Atom feed
* on using array index, vectorized operation
@ 2011-03-27  1:31 Nasser M. Abbasi
  2011-03-27 18:48 ` Nasser M. Abbasi
  2011-03-27 20:01 ` Cyrille
  0 siblings, 2 replies; 20+ messages in thread
From: Nasser M. Abbasi @ 2011-03-27  1:31 UTC (permalink / raw)


Hello;

Many times I need to operate on an array using an index
by doing some operation on the index itself as a variable
(such as shifting for example).

This below is a very simple example of what I mean.

Given an array A, I might want to do

A(i-1) := A(i)    ----------- (1)

where 'i' above is a variable which contain in it some index
locations to use to index into the array A.

In Ada, I can do the above, but I am a little clumsy in doing
it. I know I can use array slicing as in  A(1..4) := A(2..5),
but wanted to do it when the index itself is a variable, as in (1)
above. Since in other cases, I have to do more operations on the index
itself, and so it needs to be in a variable.

This is what I tried so far, and my goal to see if I can
shorten this more:

------------------------
procedure t is
i: constant array (1..4) of integer:=(2,3,4,5);
A: array(1..5) of integer := (10,20,30,40,50);

begin
   --A(2..5) := A(1..4);
   --A(i-1) := A(i);  --error

   A(i(1)-1..i(4)-1) := A(i(1)..i(4));
end t;
---------------------

Now, when I print A, it will show (20,30,40,50,50)
as expected.

But how can I change the above to do it more directly, as (1)?

In Fortran, I can do it as follows:

--------------------
program t
implicit none
integer :: A(1:5)=(/10,20,30,40,50/)
integer :: i(1:4)=(/2,3,4,5/)

A(i-1) = A(i)

end program t
---------------------

and in Matlab also

----------------------
EDU>> A=[10 20 30 40 50];
EDU>> i=2:5;
EDU>> A(i-1)=A(i)
A =
     20    30    40    50    50
-------------------------

I am sure it is possible also in Ada to make this operation
as short in syntax as it is in the other 2 systems I showed above.
I just was not able to figure the syntax yet.

thanks
--Nasser



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: on using array index, vectorized operation
  2011-03-27  1:31 on using array index, vectorized operation Nasser M. Abbasi
@ 2011-03-27 18:48 ` Nasser M. Abbasi
  2011-03-27 20:01 ` Cyrille
  1 sibling, 0 replies; 20+ messages in thread
From: Nasser M. Abbasi @ 2011-03-27 18:48 UTC (permalink / raw)


On 3/26/2011 6:31 PM, Nasser M. Abbasi wrote:
> Hello;
>
> Many times I need to operate on an array using an index
> by doing some operation on the index itself as a variable
> (such as shifting for example).
>
> This below is a very simple example of what I mean.
>
> Given an array A, I might want to do
>
> A(i-1) := A(i)    ----------- (1)
>
> where 'i' above is a variable which contain in it some index
> locations to use to index into the array A.
>
> In Ada, I can do the above, but I am a little clumsy in doing
> it. I know I can use array slicing as in  A(1..4) := A(2..5),
> but wanted to do it when the index itself is a variable, as in (1)
> above. Since in other cases, I have to do more operations on the index
> itself, and so it needs to be in a variable.
>
> This is what I tried so far, and my goal to see if I can
> shorten this more:
>
> ------------------------
> procedure t is
> i: constant array (1..4) of integer:=(2,3,4,5);
> A: array(1..5) of integer := (10,20,30,40,50);
>
> begin
>     --A(2..5) := A(1..4);
>     --A(i-1) := A(i);  --error
>
>     A(i(1)-1..i(4)-1) := A(i(1)..i(4));
> end t;
> ---------------------
>
> Now, when I print A, it will show (20,30,40,50,50)
> as expected.
>
> But how can I change the above to do it more directly, as (1)?
>
> In Fortran, I can do it as follows:
>
> --------------------
> program t
> implicit none
> integer :: A(1:5)=(/10,20,30,40,50/)
> integer :: i(1:4)=(/2,3,4,5/)
>
> A(i-1) = A(i)
>
> end program t
> ---------------------
>
> and in Matlab also
>
> ----------------------
> EDU>>  A=[10 20 30 40 50];
> EDU>>  i=2:5;
> EDU>>  A(i-1)=A(i)
> A =
>       20    30    40    50    50
> -------------------------
>
> I am sure it is possible also in Ada to make this operation
> as short in syntax as it is in the other 2 systems I showed above.
> I just was not able to figure the syntax yet.

ref(me)

I've looked more into this. It does not seem Ada support for
such 'vectorized' operations is as extensive as with Fortran
or Matlab.

There is a nice table here I found which summarizes this for
many languages

http://en.wikipedia.org/wiki/Comparison_of_programming_languages_%28array%29#Slicing

For Ada, it says under the column "Vectorized operations"  the following:

          "some, others definable5"

Any way. Without such support, I find that I need to make lots of
LOOPs for many things now in Ada. I'd rather use vectorized syntax if
possible.  Most of my Matlab code makes heavy use of vectorized
operations on arrays and matrices, which makes the code more
compact and also easier to work with.

--Nasser



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: on using array index, vectorized operation
  2011-03-27  1:31 on using array index, vectorized operation Nasser M. Abbasi
  2011-03-27 18:48 ` Nasser M. Abbasi
@ 2011-03-27 20:01 ` Cyrille
  2011-03-27 20:44   ` Nasser M. Abbasi
  1 sibling, 1 reply; 20+ messages in thread
From: Cyrille @ 2011-03-27 20:01 UTC (permalink / raw)


On Mar 27, 3:31 am, "Nasser M. Abbasi" <n...@12000.org> wrote:
> Hello;
>
> Many times I need to operate on an array using an index
> by doing some operation on the index itself as a variable
> (such as shifting for example).
>
> This below is a very simple example of what I mean.
>
> Given an array A, I might want to do
>
> A(i-1) := A(i)    ----------- (1)
>
> where 'i' above is a variable which contain in it some index
> locations to use to index into the array A.
>
> In Ada, I can do the above, but I am a little clumsy in doing
> it. I know I can use array slicing as in  A(1..4) := A(2..5),
> but wanted to do it when the index itself is a variable, as in (1)
> above. Since in other cases, I have to do more operations on the index
> itself, and so it needs to be in a variable.
>
> This is what I tried so far, and my goal to see if I can
> shorten this more:
>
> ------------------------
> procedure t is
> i: constant array (1..4) of integer:=(2,3,4,5);
> A: array(1..5) of integer := (10,20,30,40,50);
>
> begin
>    --A(2..5) := A(1..4);
>    --A(i-1) := A(i);  --error
>
>    A(i(1)-1..i(4)-1) := A(i(1)..i(4));
> end t;

you can write:

   A(A'First+1 .. A'Last) := A(A'First .. A'Last-1);





^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: on using array index, vectorized operation
  2011-03-27 20:01 ` Cyrille
@ 2011-03-27 20:44   ` Nasser M. Abbasi
  2011-03-27 21:02     ` Pascal Obry
                       ` (2 more replies)
  0 siblings, 3 replies; 20+ messages in thread
From: Nasser M. Abbasi @ 2011-03-27 20:44 UTC (permalink / raw)


On 3/27/2011 1:01 PM, Cyrille wrote:
>>
>> This is what I tried so far, and my goal to see if I can
>> shorten this more:
>>
>> ------------------------
>> procedure t is
>> i: constant array (1..4) of integer:=(2,3,4,5);
>> A: array(1..5) of integer := (10,20,30,40,50);
>>
>> begin
>>     --A(2..5) := A(1..4);
>>     --A(i-1) := A(i);  --error
>>
>>     A(i(1)-1..i(4)-1) := A(i(1)..i(4));
>> end t;
>



> you can write:
>
>     A(A'First+1 .. A'Last) := A(A'First .. A'Last-1);
>
>

Thanks, Yes, I could I suppose, but it is not really practical.

Is there a way to make

          A'First .. A'Last

into one variable, say 'i', so I can just write  i+1 or i-1 etc..?

Here is one typical equation I have, using the 'vectored' notation,
and if I have to write it in the above 'expanded' solution you showed,
then the code becomes very hard to work with and one can make an error.

Let me explain. Here is lax-wendroff scheme for 1-D advection pde, where
'u' below is the solution:

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 in the above, 'i' is the index range that I set up myself before.

In Ada, I put the above line inside a loop over 'i'.

Using your solution, I would have to write

u(u'first+1..u'last-1) :=u(u'first+1..u'last-1) -
         (a/2.0)* (u(u'first+2..u'last) - u(u'first..u'last-2))+
         (a**2)/2.0*  ( u(u'first..u'last-2)-2.0*u(u'first+1..u'last-1) +
                         u(u'first+2..u'last)) ;


ie, I had to do the index adjustment by hand, adding one, subtract one,
etc... where needed, instead of just writing i-1 or i+1 and let
the computer figure it out.


So, your solution can work, but not practical. The above also
is one simple scheme, I have such things that work on 2D grids,
which is even more complicated.

If I can figure how to make the index itself a variable, like
I can with Fortran or Matlab for example, then I'd be happy :)

--Nasser



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: on using array index, vectorized operation
  2011-03-27 20:44   ` Nasser M. Abbasi
@ 2011-03-27 21:02     ` Pascal Obry
  2011-03-27 21:30     ` Shark8
  2011-03-27 22:09     ` Phil Clayton
  2 siblings, 0 replies; 20+ messages in thread
From: Pascal Obry @ 2011-03-27 21:02 UTC (permalink / raw)
  To: nma

Le 27/03/2011 22:44, Nasser M. Abbasi a �crit :

> Is there a way to make
>
> A'First .. A'Last

This is A'Range,

> into one variable, say 'i', so I can just write i+1 or i-1 etc..?

But there is no generic way of storing a range into a variable, so the 
above is not possible.

One can do:

    subtype My_Range is Natural range I + 2 .. I + 9;

    A (My_Range) := ...

Does that solves your problem?

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] 20+ messages in thread

* Re: on using array index, vectorized operation
  2011-03-27 20:44   ` Nasser M. Abbasi
  2011-03-27 21:02     ` Pascal Obry
@ 2011-03-27 21:30     ` Shark8
  2011-03-27 22:00       ` Nasser M. Abbasi
  2011-03-27 22:09     ` Phil Clayton
  2 siblings, 1 reply; 20+ messages in thread
From: Shark8 @ 2011-03-27 21:30 UTC (permalink / raw)


On Mar 27, 2:44 pm, "Nasser M. Abbasi" <n...@12000.org> wrote:
>
> Thanks, Yes, I could I suppose, but it is not really practical.
>
> Is there a way to make
>
>           A'First .. A'Last
>
> into one variable, say 'i', so I can just write  i+1 or i-1 etc..?

No; see Pascal's answer.
I would actually suggest making it even more generic; something along
the lines of:


Subtype Subrange is XXX Range XXX'Succ(XXX'First)..XXX'Last;
or Range XXX'First..XXX'Pred'(XXX'Last); as needed, where XXX is your
index-type.

>Using your solution, I would have to write
>
>u(u'first+1..u'last-1) :=u(u'first+1..u'last-1) -
>         (a/2.0)* (u(u'first+2..u'last) - u(u'first..u'last-2))+
>         (a**2)/2.0*  ( u(u'first..u'last-2)-2.0*u(u'first+1..u'last-1) +
>                         u(u'first+2..u'last));

The above could probably* then be rewritten as:

Declare
 SubType SubRange_1 is Natural Range U'Succ(U'First)..U'Pred(U'Last);
 SubType SubRange_2 is Natural Range U'Succ(SubRange_1'First)..U'Last;
 SubType SubRange_3 is Natural Range U'First..U'Pred(SubRange_1'Last);
Begin
  u(SubRange_1):= u(SubRange_1) -
      (a/2.0) * ( u(SubRange_2) - u(SubRange_3) ) +
      (a**2)/2.0 * ( u(SubRange_3) - 2.0*u(SubRange_1) +
u(SubRange_2) );
End;

* I didn't run this through my compiler.
I'm sorry about the poor naming of the subtypes, the technical [math]
term escapes me at the moment, but I think it does illustrate what is
going on.



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: on using array index, vectorized operation
  2011-03-27 21:30     ` Shark8
@ 2011-03-27 22:00       ` Nasser M. Abbasi
  2011-03-27 22:37         ` Phil Clayton
  0 siblings, 1 reply; 20+ messages in thread
From: Nasser M. Abbasi @ 2011-03-27 22:00 UTC (permalink / raw)


Thanks Pascal and Shark8;

Yes, Pascal solution is a big improvment.

Here is what I have now: (will use the attributes 'succ and 'pred
later, but for now, I just wanted to see the concept first)

Also, notice, I need to use integer, not natural, for the indices, since
those can become negative in general.

------------- example ----------
procedure foo is

type buffer_t is array(integer range<>) of float;

u : buffer_t(-1..10) := (others=>0.0);

subtype r        is integer range u'first+1 .. u'last-1;
subtype r_plus_1 is integer range r'first+1 .. r'last+1;

begin

    u(r) := u(r) -  u(r_plus_1);

end foo;
----------------------

The above is workable solution for me, at least I avoid the
loops.

Only problem now is that I need to figure the castings I need
to do to make the compile happy, Since now I get the error:


$ gnatmake foo.adb
gcc-4.4 -c foo.adb
foo.adb:10:14: there is no applicable operator "-" for type "buffer_t" defined at line 2
gnatmake: "foo.adb" compilation error
$

Will look at this now, how best to solve this? I understand
that it want me to define a "-" operator for buffer_t. I really do
not want to cast things, I need to find the best solution to this.

May be I need to define a function "-" for buffer_t ?

Ok, back to editing and trying things :)

But I am happy now that at least I can avoid explicit loops if needed.

--Nasser



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: on using array index, vectorized operation
  2011-03-27 20:44   ` Nasser M. Abbasi
  2011-03-27 21:02     ` Pascal Obry
  2011-03-27 21:30     ` Shark8
@ 2011-03-27 22:09     ` Phil Clayton
  2011-03-27 22:12       ` Nasser M. Abbasi
  2011-03-27 22:23       ` Nasser M. Abbasi
  2 siblings, 2 replies; 20+ messages in thread
From: Phil Clayton @ 2011-03-27 22:09 UTC (permalink / raw)


On Mar 27, 9:44 pm, "Nasser M. Abbasi" <n...@12000.org> wrote:
> Let me explain. Here is lax-wendroff scheme for 1-D advection pde, where
> 'u' below is the solution:
>
> 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 in the above, 'i' is the index range that I set up myself before.
>
> In Ada, I put the above line inside a loop over 'i'.

I notice that the rhs mentions u(i+1) and u(i-1) so depending on
whether you're decrementing or incrementing i, one of these will be
overwritten on a previous loop iteration.  Presumably that isn't
intended (looking at your vectorized code)?


> Using your solution, I would have to write
>
> u(u'first+1..u'last-1) :=u(u'first+1..u'last-1) -
>          (a/2.0)* (u(u'first+2..u'last) - u(u'first..u'last-2))+
>          (a**2)/2.0*  ( u(u'first..u'last-2)-2.0*u(u'first+1..u'last-1) +
>                          u(u'first+2..u'last)) ;

Do we now have vectorized arithmetic operations, e.g. + on array
types?

Phil



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: on using array index, vectorized operation
  2011-03-27 22:09     ` Phil Clayton
@ 2011-03-27 22:12       ` Nasser M. Abbasi
  2011-03-27 22:23       ` Nasser M. Abbasi
  1 sibling, 0 replies; 20+ messages in thread
From: Nasser M. Abbasi @ 2011-03-27 22:12 UTC (permalink / raw)


On 3/27/2011 3:09 PM, Phil Clayton wrote:
> On Mar 27, 9:44 pm, "Nasser M. Abbasi"<n...@12000.org>  wrote:
>> Let me explain. Here is lax-wendroff scheme for 1-D advection pde, where
>> 'u' below is the solution:
>>
>> 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 in the above, 'i' is the index range that I set up myself before.
>>
>> In Ada, I put the above line inside a loop over 'i'.
>

> I notice that the rhs mentions u(i+1) and u(i-1) so depending on
> whether you're decrementing or incrementing i, one of these will be
> overwritten on a previous loop iteration.  Presumably that isn't
> intended (looking at your vectorized code)?
>

Yes, sorry, ofcourse in the actuall code I have

LOOP over i
    u_new(i) = u(i)- .....
END LOOP

But when I posted it to this newsgroup, I was editing things by hand
to show.

Here is the actual code

http://12000.org/my_notes/solve_advection_1D_in_Ada/source/lax_wendroff_pkg.adb

>
>> Using your solution, I would have to write
>>
>> u(u'first+1..u'last-1) :=u(u'first+1..u'last-1) -
>>           (a/2.0)* (u(u'first+2..u'last) - u(u'first..u'last-2))+
>>           (a**2)/2.0*  ( u(u'first..u'last-2)-2.0*u(u'first+1..u'last-1) +
>>                           u(u'first+2..u'last)) ;
>
> Do we now have vectorized arithmetic operations, e.g. + on array
> types?
>
> Phil

--Nasser




^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: on using array index, vectorized operation
  2011-03-27 22:09     ` Phil Clayton
  2011-03-27 22:12       ` Nasser M. Abbasi
@ 2011-03-27 22:23       ` Nasser M. Abbasi
  2011-03-29  2:50         ` Randy Brukardt
  1 sibling, 1 reply; 20+ messages in thread
From: Nasser M. Abbasi @ 2011-03-27 22:23 UTC (permalink / raw)


On 3/27/2011 3:09 PM, Phil Clayton wrote:

>
> Do we now have vectorized arithmetic operations, e.g. + on array
> types?
>

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;
-------------------

$ gnatmake foo2.adb
gcc-4.4 -c foo2.adb
foo2.adb:7:09: expected type universal integer
foo2.adb:7:09: found type "array_t" defined at line 3
gnatmake: "foo2.adb" compilation error

I am trying to figure a solution to this problem now. But I am
just learning Ada myself.

But I have to admit when it comes to working with arrays and such,
these things are easier in Fortran:

-------------------
program t
implicit none
integer :: A(1:5) = 0

A = A + 1

print *,A

end program t
-----------------

$ gfortran -Wall foo.f90
$ ./a.out
            1           1           1           1           1
$

--Nasser



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: on using array index, vectorized operation
  2011-03-27 22:00       ` Nasser M. Abbasi
@ 2011-03-27 22:37         ` Phil Clayton
  2011-03-27 22:43           ` Nasser M. Abbasi
  0 siblings, 1 reply; 20+ messages in thread
From: Phil Clayton @ 2011-03-27 22:37 UTC (permalink / raw)


On Mar 27, 11:00 pm, "Nasser M. Abbasi" <n...@12000.org> wrote:
> Only problem now is that I need to figure the castings I need
> to do to make the compile happy, Since now I get the error:
>
> $ gnatmake foo.adb
> gcc-4.4 -c foo.adb
> foo.adb:10:14: there is no applicable operator "-" for type "buffer_t" defined at line 2
> gnatmake: "foo.adb" compilation error
> $
>
> Will look at this now, how best to solve this? I understand
> that it want me to define a "-" operator for buffer_t. I really do
> not want to cast things, I need to find the best solution to this.
>
> May be I need to define a function "-" for buffer_t ?

(So please ignore my previous question.)

I had a similar quandary a few years ago where it was necessary to
describe results of vectorized operations (from Simulink as it
happens) using a language that had no natural support for
vectorization.  The thought of defining variants of operations to work
on 1-D arrays, another set of variants for 2-D arrays etc. was too
horrendous.  It was far simpler to promote scalar operations using a
loop, like in your example.  (We actually produced a vectorized meta-
notation that allowed an expression form of loop like 'for-aggregates'
that I've mentioned before, so didn't need to deal with temporary
variables.)  My advice would be to stick to the loop version, with
temporary variables if necessary, as that is most traceable to the
original text and surely the most maintainable.

Phil



> But I am happy now that at least I can avoid explicit loops if needed.



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: on using array index, vectorized operation
  2011-03-27 22:37         ` Phil Clayton
@ 2011-03-27 22:43           ` Nasser M. Abbasi
  2011-03-27 22:59             ` Phil Clayton
  0 siblings, 1 reply; 20+ messages in thread
From: Nasser M. Abbasi @ 2011-03-27 22:43 UTC (permalink / raw)


On 3/27/2011 3:37 PM, Phil Clayton wrote:
>
> My advice would be to stick to the loop version, with
> temporary variables if necessary, as that is most traceable to the
> original text and surely the most maintainable.
>
> Phil
>

I think you are right in this advice :)

But it is hard to go back to using explicit loops when one
is used to working with vectorized operations.

I would also think loops will be slower, because vectorized
operations could be much more optimized by the compiler and such.

Any way, no language is perfect.

--Nasser



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: on using array index, vectorized operation
  2011-03-27 22:43           ` Nasser M. Abbasi
@ 2011-03-27 22:59             ` Phil Clayton
  0 siblings, 0 replies; 20+ messages in thread
From: Phil Clayton @ 2011-03-27 22:59 UTC (permalink / raw)


On Mar 27, 11:43 pm, "Nasser M. Abbasi" <n...@12000.org> wrote:
> But it is hard to go back to using explicit loops when one
> is used to working with vectorized operations.
>
> I would also think loops will be slower, because vectorized
> operations could be much more optimized by the compiler and such.

Something along those lines was discussed not so long ago:
http://groups.google.com/group/comp.lang.ada/browse_thread/thread/99210dd26e04d959#


> Any way, no language is perfect.

I find the language containing just the word "no" perfect in many
situations.  Unfortunately, so does my bank.

Phil



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: on using array index, vectorized operation
  2011-03-27 22:23       ` Nasser M. Abbasi
@ 2011-03-29  2:50         ` Randy Brukardt
  2011-03-29  4:55           ` Nasser M. Abbasi
  0 siblings, 1 reply; 20+ messages in thread
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	[flat|nested] 20+ messages in thread

* Re: on using array index, vectorized operation
  2011-03-29  2:50         ` Randy Brukardt
@ 2011-03-29  4:55           ` Nasser M. Abbasi
  2011-03-29 20:11             ` Phil Clayton
  0 siblings, 1 reply; 20+ messages in thread
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	[flat|nested] 20+ messages in thread

* Re: on using array index, vectorized operation
  2011-03-29  4:55           ` Nasser M. Abbasi
@ 2011-03-29 20:11             ` Phil Clayton
  2011-03-29 21:17               ` Nasser M. Abbasi
  0 siblings, 1 reply; 20+ messages in thread
From: Phil Clayton @ 2011-03-29 20:11 UTC (permalink / raw)


On Mar 29, 5:55 am, "Nasser M. Abbasi" <n...@12000.org> wrote:
> 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's worth observing that you're using vectorized subscripting, not
just vectorized arithmetic.  It should be possible to write a function
that does the vectorized subscript, e.g. Sub(A, X) = B such that B(i)
= A(X(i)).  Unfortunately, if you use real arrays for the i+1 in your
example, you'll have real subscripts.  That may be acceptable when
modelling e.g. in Matlab but not in an implementation.  So you may
need + and - on arrays of your index type.  It all depends what you
intend to use your code for.

Phil

P.S. I still think Ada should allow us to write something like

  u (2 .. 5) := (for i in 2 .. 5 =>
                  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)));

(which avoids the temporary variable that the equivalent loop
requires).  This enables on-the-fly vectorization by promoting scalar
operations inline in expressions.  For example, if you didn't have a
version of some function F vectorized in its second argument, you
could write

  (for I in B'Range => F(A, B(I), C))



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: on using array index, vectorized operation
  2011-03-29 20:11             ` Phil Clayton
@ 2011-03-29 21:17               ` Nasser M. Abbasi
  2011-03-29 22:49                 ` Phil Clayton
  0 siblings, 1 reply; 20+ messages in thread
From: Nasser M. Abbasi @ 2011-03-29 21:17 UTC (permalink / raw)


On 3/29/2011 1:11 PM, Phil Clayton wrote:

>  Unfortunately, if you use real arrays for the i+1 in your
> example, you'll have real subscripts.  That may be acceptable when
> modelling e.g. in Matlab but not in an implementation.

I am a little confused on the above.

What do you mean by "you'll have real subscripts" ?

Are you talking about Fortran now? Lets forget Matlab, since
Matlab is special case. (default is double for everything, etc...)

For Fortran, why would the subscripts have to be floating point
numbers if the array content happened to be floating point values?

Or are you talking about Ada here?

> Phil
>
> P.S. I still think Ada should allow us to write something like
>
>    u (2 .. 5) := (for i in 2 .. 5 =>
>                    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)));
>
> (which avoids the temporary variable that the equivalent loop
> requires).


Thats nice if possible to do. But just being able to write  in Ada
an index array as a variable and then write

i := 2..5;  -- using the correct range etc... syntax  for Ada

and then write
  
  u(i) := u(i) + u(i-1) - ......

would be nice.

which is the 'standard' way in Fortran and Matlab type synatx.

> This enables on-the-fly vectorization by promoting scalar
> operations inline in expressions.  For example, if you didn't have a
> version of some function F vectorized in its second argument, you
> could write
>
>    (for I in B'Range =>  F(A, B(I), C))

I do think that Fortran still has more support and build-in
functions (called intrinsics) and syntax to working with vectors
and matrices than Ada does, at least it seems it requires less
work to set things up.

But again, this is what Fortran was originally designed for, so this is
not too surprising. Each language has its strong and not too strong
areas.

--Nasser



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: on using array index, vectorized operation
  2011-03-29 21:17               ` Nasser M. Abbasi
@ 2011-03-29 22:49                 ` Phil Clayton
  2011-03-29 23:47                   ` Nasser M. Abbasi
  0 siblings, 1 reply; 20+ messages in thread
From: Phil Clayton @ 2011-03-29 22:49 UTC (permalink / raw)


On Mar 29, 10:17 pm, "Nasser M. Abbasi" <n...@12000.org> wrote:
> On 3/29/2011 1:11 PM, Phil Clayton wrote:
>
> >  Unfortunately, if you use real arrays for the i+1 in your
> > example, you'll have real subscripts.  That may be acceptable when
> > modelling e.g. in Matlab but not in an implementation.
>
> I am a little confused on the above.
>
> What do you mean by "you'll have real subscripts" ?
>
> Are you talking about Fortran now? Lets forget Matlab, since
> Matlab is special case. (default is double for everything, etc...)
>
> For Fortran, why would the subscripts have to be floating point
> numbers if the array content happened to be floating point values?
>
> Or are you talking about Ada here?

Yes, I meant the Ada example after being updated to use vectorized
subscripting.  Sorry for the confusion.


> > P.S. I still think Ada should allow us to write something like
>
> >    u (2 .. 5) := (for i in 2 .. 5 =>
> >                    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)));
>
> > (which avoids the temporary variable that the equivalent loop
> > requires).
>
> Thats nice if possible to do. But just being able to write  in Ada
> an index array as a variable and then write
>
> i := 2..5;  -- using the correct range etc... syntax  for Ada
>
> and then write
>
>   u(i) := u(i) + u(i-1) - ......
>
> would be nice.
>
> which is the 'standard' way in Fortran and Matlab type synatx.

Yes, nicer still for the kind of algorithm you have.


> > This enables on-the-fly vectorization by promoting scalar
> > operations inline in expressions.  For example, if you didn't have a
> > version of some function F vectorized in its second argument, you
> > could write
>
> >    (for I in B'Range =>  F(A, B(I), C))
>
> I do think that Fortran still has more support and build-in
> functions (called intrinsics) and syntax to working with vectors
> and matrices than Ada does, at least it seems it requires less
> work to set things up.
>
> But again, this is what Fortran was originally designed for, so this is
> not too surprising. Each language has its strong and not too strong
> areas.

I believe these vectorization features first appeared in Fortran 90,
about 33 years after the very first FORTRAN.  I guess that gives Ada
until 2016 if it is to follow suit...

Phil



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: on using array index, vectorized operation
  2011-03-29 22:49                 ` Phil Clayton
@ 2011-03-29 23:47                   ` Nasser M. Abbasi
  2011-03-30 13:00                     ` Robert A Duff
  0 siblings, 1 reply; 20+ messages in thread
From: Nasser M. Abbasi @ 2011-03-29 23:47 UTC (permalink / raw)


On 3/29/2011 3:49 PM, Phil Clayton wrote:

> I believe these vectorization features first appeared in Fortran 90,

Correct

> about 33 years after the very first FORTRAN.  I guess that gives Ada
> until 2016 if it is to follow suit...
>
> Phil

And may be add 3-5 more years for compilers to implement the new
standard? so may be 2020?

That is _only_ 9 years from now. Can't wait :)

--Nasser



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: on using array index, vectorized operation
  2011-03-29 23:47                   ` Nasser M. Abbasi
@ 2011-03-30 13:00                     ` Robert A Duff
  0 siblings, 0 replies; 20+ messages in thread
From: Robert A Duff @ 2011-03-30 13:00 UTC (permalink / raw)


"Nasser M. Abbasi" <nma@12000.org> writes:

> And may be add 3-5 more years for compilers to implement the new
> standard? so may be 2020?

Well, GNAT has already implemented a large portion of Ada 2012.

I think the next Ada after 2012 should be 2020, so we can make
silly jokes about 20/20 hindsight.

- Bob



^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2011-03-30 13:00 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-03-27  1:31 on using array index, vectorized operation Nasser M. Abbasi
2011-03-27 18:48 ` Nasser M. Abbasi
2011-03-27 20:01 ` Cyrille
2011-03-27 20:44   ` Nasser M. Abbasi
2011-03-27 21:02     ` Pascal Obry
2011-03-27 21:30     ` Shark8
2011-03-27 22:00       ` Nasser M. Abbasi
2011-03-27 22:37         ` Phil Clayton
2011-03-27 22:43           ` Nasser M. Abbasi
2011-03-27 22:59             ` Phil Clayton
2011-03-27 22:09     ` Phil Clayton
2011-03-27 22:12       ` Nasser M. Abbasi
2011-03-27 22:23       ` Nasser M. Abbasi
2011-03-29  2:50         ` Randy Brukardt
2011-03-29  4:55           ` Nasser M. Abbasi
2011-03-29 20:11             ` Phil Clayton
2011-03-29 21:17               ` Nasser M. Abbasi
2011-03-29 22:49                 ` Phil Clayton
2011-03-29 23:47                   ` Nasser M. Abbasi
2011-03-30 13:00                     ` Robert A Duff

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox