comp.lang.ada
 help / color / mirror / Atom feed
* basic question on adding 2 arrays
@ 2014-07-13  3:34 Nasser M. Abbasi
  2014-07-13  4:09 ` Nasser M. Abbasi
  0 siblings, 1 reply; 7+ messages in thread
From: Nasser M. Abbasi @ 2014-07-13  3:34 UTC (permalink / raw)


I am really rusty in Ada since I have not used it for sometime.

Is there an easy way to add one slice of an array to another
without having to make an explicit loop?  Here is MWE

------------------------------------------------
with Ada.Text_IO;                       use Ada.Text_IO;

procedure foo is
    nPoints : constant Integer := 100;
    type grid_type is array (1 .. nPoints) of Float;
    now : grid_type := (others => 0.0);
    next: grid_type := now;
    begin
      next(2..now'length-1) := 1/2*
        (now(1..now'length-1)+now(3..now'length));
end foo;
--------------------------------------------------

I am basically trying to update an array (this is a finite difference
scheme).  The error is that "+" is not defined for the grid_type,
which I understand ofcourse. But wanted to ask if there is a way
to do this in-line without having to define a method for this.

For example, in Matlab or Fortran something like this works:

    next(2:end-1) = 1/2*(now(1:end-2)+now(3:end));

It is not big deal to defined "+" for the grid_type, but
wanted to check if there might be a way to do it without,
or a better way to do update.

thanks,
--Nasser

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

* Re: basic question on adding 2 arrays
  2014-07-13  3:34 basic question on adding 2 arrays Nasser M. Abbasi
@ 2014-07-13  4:09 ` Nasser M. Abbasi
  2014-07-13  4:35   ` Nasser M. Abbasi
  2014-07-13  6:33   ` Jeffrey Carter
  0 siblings, 2 replies; 7+ messages in thread
From: Nasser M. Abbasi @ 2014-07-13  4:09 UTC (permalink / raw)


On 7/12/2014 10:34 PM, Nasser M. Abbasi wrote:

> ------------------------------------------------
> with Ada.Text_IO;                       use Ada.Text_IO;
>
> procedure foo is
>      nPoints : constant Integer := 100;
>      type grid_type is array (1 .. nPoints) of Float;
>      now : grid_type := (others => 0.0);
>      next: grid_type := now;
>      begin
>        next(2..now'length-1) := 1/2*
>          (now(1..now'length-1)+now(3..now'length));
> end foo;
> --------------------------------------------------
>
> I am basically trying to update an array (this is a finite difference
> scheme).  The error is that "+" is not defined for the grid_type,
> which I understand ofcourse. But wanted to ask if there is a way
> to do this in-line without having to define a method for this.
>
> For example, in Matlab or Fortran something like this works:
>
>      next(2:end-1) = 1/2*(now(1:end-2)+now(3:end));
>

This is what I tried. But after making special
"+" to add the 2 slices of grid_type, by making
new grid_type2 which is 2 elements smaller than
grid_type, how does not tell Ada to move this
grid_type2 into grid_type since they are of
different type?  Do I need another loop for this?

----------------------------
with Ada.Text_IO; use Ada.Text_IO;

procedure foo is
    nPoints : constant Integer := 100;
    type grid_type is array (1 .. nPoints) of Float;
    type grid_type2 is array (1 .. nPoints - 2) of Float;
    now  : grid_type := (others => 0.0);
    tmp:   grid_type2; -- just to do the slices
    next : grid_type := (others => 0.0);

    function "+" (left, right : in grid_type2) return grid_type2 is
       res : grid_type2;
    begin
       for i in grid_type2'Range loop
          res (i) := left (i) + right (i);
       end loop;
       return res;
    end "+";

begin
    tmp :=
      grid_type2 (now (2 .. now'Length - 1)) +
        grid_type2 (now (3 .. now'Length));
    
    next(2..now'length-1) := tmp;  -- stuck on this one ;)
    
end foo;
-----------------------------

I am sure there must be a better way to do all this, I can't
be making new type for each different slice I want to
work with?

--Nasser

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

* Re: basic question on adding 2 arrays
  2014-07-13  4:09 ` Nasser M. Abbasi
@ 2014-07-13  4:35   ` Nasser M. Abbasi
  2014-07-13  6:33   ` Jeffrey Carter
  1 sibling, 0 replies; 7+ messages in thread
From: Nasser M. Abbasi @ 2014-07-13  4:35 UTC (permalink / raw)


Ok, the final scoope. Using slices does not seem
to be worth the trouble. Went back to making
an explicit loop. Much simpler:

--------------------------------------
with Ada.Text_IO; use Ada.Text_IO;

procedure foo is
    nPoints : constant Integer := 100;
    type grid_type is array (1 .. nPoints) of Float;
    now  : grid_type := (others => 0.0);
    next : grid_type := (others => 0.0);
begin

    for i in 2..next'length-1 loop
       next(i):= now(i-1)+now(i+1);
    end loop;

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

The above for loop is the one I was trying to
emulate using below. But I'll stick to the
above in Ada, I do not think Ada supports
array operations as easily as Fortran. But it is
ok, the above loop is not too bad. Will live
with it.  (I need to learn Ada better also)

--Nasser
On 7/12/2014 11:09 PM, Nasser M. Abbasi wrote:
> On 7/12/2014 10:34 PM, Nasser M. Abbasi wrote:
>
>> ------------------------------------------------
>> with Ada.Text_IO;                       use Ada.Text_IO;
>>
>> procedure foo is
>>       nPoints : constant Integer := 100;
>>       type grid_type is array (1 .. nPoints) of Float;
>>       now : grid_type := (others => 0.0);
>>       next: grid_type := now;
>>       begin
>>         next(2..now'length-1) := 1/2*
>>           (now(1..now'length-1)+now(3..now'length));
>> end foo;
>> --------------------------------------------------
>>
>> I am basically trying to update an array (this is a finite difference
>> scheme).  The error is that "+" is not defined for the grid_type,
>> which I understand ofcourse. But wanted to ask if there is a way
>> to do this in-line without having to define a method for this.
>>
>> For example, in Matlab or Fortran something like this works:
>>
>>       next(2:end-1) = 1/2*(now(1:end-2)+now(3:end));
>>
>
> This is what I tried. But after making special
> "+" to add the 2 slices of grid_type, by making
> new grid_type2 which is 2 elements smaller than
> grid_type, how does not tell Ada to move this
> grid_type2 into grid_type since they are of
> different type?  Do I need another loop for this?
>
> ----------------------------
> with Ada.Text_IO; use Ada.Text_IO;
>
> procedure foo is
>      nPoints : constant Integer := 100;
>      type grid_type is array (1 .. nPoints) of Float;
>      type grid_type2 is array (1 .. nPoints - 2) of Float;
>      now  : grid_type := (others => 0.0);
>      tmp:   grid_type2; -- just to do the slices
>      next : grid_type := (others => 0.0);
>
>      function "+" (left, right : in grid_type2) return grid_type2 is
>         res : grid_type2;
>      begin
>         for i in grid_type2'Range loop
>            res (i) := left (i) + right (i);
>         end loop;
>         return res;
>      end "+";
>
> begin
>      tmp :=
>        grid_type2 (now (2 .. now'Length - 1)) +
>          grid_type2 (now (3 .. now'Length));
>
>      next(2..now'length-1) := tmp;  -- stuck on this one ;)
>
> end foo;
> -----------------------------
>
> I am sure there must be a better way to do all this, I can't
> be making new type for each different slice I want to
> work with?
>
> --Nasser
>

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

* Re: basic question on adding 2 arrays
  2014-07-13  4:09 ` Nasser M. Abbasi
  2014-07-13  4:35   ` Nasser M. Abbasi
@ 2014-07-13  6:33   ` Jeffrey Carter
  2014-07-13 10:10     ` AdaMagica
  1 sibling, 1 reply; 7+ messages in thread
From: Jeffrey Carter @ 2014-07-13  6:33 UTC (permalink / raw)


On 07/12/2014 09:09 PM, Nasser M. Abbasi wrote:
>
> This is what I tried. But after making special
> "+" to add the 2 slices of grid_type, by making
> new grid_type2 which is 2 elements smaller than
> grid_type, how does not tell Ada to move this
> grid_type2 into grid_type since they are of
> different type?  Do I need another loop for this?


type Base_Grid is array (Positive range <>) of Float;
subtype Grid_Type is Base_Grid (1 .. Npoints);

function "+" (Left : in Base_Grid; Right : in Base_Grid) return Base_Grid with
Pre => Left'Length = Right'Length;

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

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


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

* Re: basic question on adding 2 arrays
  2014-07-13  6:33   ` Jeffrey Carter
@ 2014-07-13 10:10     ` AdaMagica
  2014-07-13 16:25       ` Jacob Sparre Andersen
  2014-07-13 21:53       ` Jeffrey Carter
  0 siblings, 2 replies; 7+ messages in thread
From: AdaMagica @ 2014-07-13 10:10 UTC (permalink / raw)


On Sunday, July 13, 2014 8:33:57 AM UTC+2, Jeffrey Carter wrote:
> function "+" (Left : in Base_Grid; Right : in Base_Grid) return Base_Grid with
> Pre => Left'Length = Right'Length;
>
> Next (Next'First + 1 .. Next'Last - 1) :=
>     Next (Next'First .. Next'Last - 2) +
>     Next (Next'First + 2 .. Next'Last);

OK, one can do this, but is it better than Nasser's?

>    for i in 2..next'length-1 loop
>       next(i):= now(i-1)+now(i+1);
>    end loop;


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

* Re: basic question on adding 2 arrays
  2014-07-13 10:10     ` AdaMagica
@ 2014-07-13 16:25       ` Jacob Sparre Andersen
  2014-07-13 21:53       ` Jeffrey Carter
  1 sibling, 0 replies; 7+ messages in thread
From: Jacob Sparre Andersen @ 2014-07-13 16:25 UTC (permalink / raw)


AdaMagica wrote:
> On Sunday, July 13, 2014 8:33:57 AM UTC+2, Jeffrey Carter wrote:

>> Next (Next'First + 1 .. Next'Last - 1) :=
>>     Next (Next'First .. Next'Last - 2) +
>>     Next (Next'First + 2 .. Next'Last);
>
> OK, one can do this, but is it better than Nasser's?
>
>>    for i in 2..next'length-1 loop
>>       next(i):= now(i-1)+now(i+1);
>>    end loop;

I would say that it depends on how the model is formulated, but without
that knowledge Nasser's version looks easier to understand.

Nasser's version also has the benefit of being safe in case of
by-reference passing of arrays.

Greetings,

Jacob
-- 
PNG: Pretty Nice Graphics

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

* Re: basic question on adding 2 arrays
  2014-07-13 10:10     ` AdaMagica
  2014-07-13 16:25       ` Jacob Sparre Andersen
@ 2014-07-13 21:53       ` Jeffrey Carter
  1 sibling, 0 replies; 7+ messages in thread
From: Jeffrey Carter @ 2014-07-13 21:53 UTC (permalink / raw)


On 07/13/2014 03:10 AM, AdaMagica wrote:
> On Sunday, July 13, 2014 8:33:57 AM UTC+2, Jeffrey Carter wrote:
>> function "+" (Left : in Base_Grid; Right : in Base_Grid) return Base_Grid with
>> Pre => Left'Length = Right'Length;
>>
>> Next (Next'First + 1 .. Next'Last - 1) :=
>>      Next (Next'First .. Next'Last - 2) +
>>      Next (Next'First + 2 .. Next'Last);
>
> OK, one can do this, but is it better than Nasser's?
>
>>     for i in 2..next'length-1 loop
>>        next(i):= now(i-1)+now(i+1);
>>     end loop;

That's a different question, and depends on the definition of "better".

Using 'Length rather than 'Last is probably not a good idea for defining an 
index into an array.

If the problem domain has lots of these partial-array operations, then defining 
and using such operators might be more readable. If not, explicit loops might be 
better. If these arrays are very large and space or time are tight, one might 
need to concern oneself with low-level questions such as whether using an array 
operator results in a temporary result and extra copy.

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


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

end of thread, other threads:[~2014-07-13 21:53 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-07-13  3:34 basic question on adding 2 arrays Nasser M. Abbasi
2014-07-13  4:09 ` Nasser M. Abbasi
2014-07-13  4:35   ` Nasser M. Abbasi
2014-07-13  6:33   ` Jeffrey Carter
2014-07-13 10:10     ` AdaMagica
2014-07-13 16:25       ` Jacob Sparre Andersen
2014-07-13 21:53       ` Jeffrey Carter

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