From: Peter C. Chapin on 31 Jan 2010 21:11 This is something of a newbie question.. I'm working with a two dimensional array of floating point values. Lets call it A. The array has type type Matrix is array(Positive range <>, Positive range <>) of Floating_Type; I need to exchange two rows in this array. What I'd like to do is something along these lines: Temp_Array := A(I, 1 .. Size); A(I, 1 .. Size) := A(K, 1 .. Size); A(K, 1 .. Size) := Temp_Array; The compiler (GNAT GPL 2009) has a problem with this syntax and, after looking into it some, I think that's because slicing only works for one dimensional arrays. Fair enough. So I thought, "Perhaps A needs to be an array of arrays." type Matrix is array(Positive range <>) of WHAT_EXACTLY? Apparently the component type of an array needs to be fully constrained (which again makes sense) yet I don't know the size I'll want to use at the point where this type is declared. So now I'm thinking that I'll have to write a procedure to explicity swap each row element one at a time. Of course this is not a terrible thing, but I'm wondering if there is a more elegant way that I'm missing. I have some confidence that the compiler can optimize slice operations reasonably well. I'm less confident about its ability to optimize element by element operations (maybe I'm overly pessimistic). Peter
From: Jeffrey R. Carter on 31 Jan 2010 23:42 Peter C. Chapin wrote: > > type Matrix is array(Positive range <>, Positive range <>) of Floating_Type; > > I need to exchange two rows in this array. What I'd like to do is something > along these lines: > > Temp_Array := A(I, 1 .. Size); > A(I, 1 .. Size) := A(K, 1 .. Size); > A(K, 1 .. Size) := Temp_Array; > > The compiler (GNAT GPL 2009) has a problem with this syntax and, after looking > into it some, I think that's because slicing only works for one dimensional > arrays. Fair enough. That's correct: slicing is only defined for one-D arrays. > So I thought, "Perhaps A needs to be an array of arrays." > > type Matrix is array(Positive range <>) of WHAT_EXACTLY? Row_Vector? > Apparently the component type of an array needs to be fully constrained (which > again makes sense) yet I don't know the size I'll want to use at the point > where this type is declared. Correct again: array components must be definite. I'm not aware of a solution other than the brute force approach. -- Jeff Carter "Gentlemen, you can't fight in here. This is the War Room!" Dr. Strangelove 30
From: Niklas Holsti on 1 Feb 2010 01:55 Peter C. Chapin wrote: > This is something of a newbie question.. > > I'm working with a two dimensional array of floating point values. Lets call > it A. The array has type > > type Matrix is array(Positive range <>, Positive range <>) of Floating_Type; > > I need to exchange two rows in this array. What I'd like to do is something > along these lines: > > Temp_Array := A(I, 1 .. Size); > A(I, 1 .. Size) := A(K, 1 .. Size); > A(K, 1 .. Size) := Temp_Array; > > The compiler (GNAT GPL 2009) has a problem with this syntax and, after looking > into it some, I think that's because slicing only works for one dimensional > arrays. Fair enough. > > So I thought, "Perhaps A needs to be an array of arrays." > > type Matrix is array(Positive range <>) of WHAT_EXACTLY? > > Apparently the component type of an array needs to be fully constrained (which > again makes sense) yet I don't know the size I'll want to use at the point > where this type is declared. One solution -- which may not match your design in other respects -- is to make the Matrix an array of accesses to rows: type Row is array (Positive range <>) of Float; type Row_Ref is access Row; type Matrix is array (Positive range <>) of Row_Ref; Exchanging two rows is then very quick: Temp_Ref := A(I); A(I) := A(K); A(K) := Temp_Ref; However, you now have to allocate the rows using "new Row (1 .. Size)" and perhaps later deallocate them using Unchecked_Deallocation. Another solution -- which perhaps you have considered -- is to use a generic package to define row and matrix types: generic Size : Positive; package Matrices is type Row is array (1 .. Size) of Float; type Matrix is array (1 .. Size) of Row; end Matrices; However, this will probably force some other parts of your code to become generic, too, parametrized either by a Size, or by an instance of Matrices. -- Niklas Holsti Tidorum Ltd niklas holsti tidorum fi . @ .
From: Dmitry A. Kazakov on 1 Feb 2010 03:37 On Sun, 31 Jan 2010 21:11:12 -0500, Peter C. Chapin wrote: > So I thought, "Perhaps A needs to be an array of arrays." > > type Matrix is array(Positive range <>) of WHAT_EXACTLY? > > Apparently the component type of an array needs to be fully constrained (which > again makes sense) Not really. Arrays should have been allowed to have discriminants. That was missed in the language design. If they had discriminants you could write: type Row is array (Positive range <>) of Float; type Matrix (Width : Positive) is array (Positive range <>) of Row (1..Width); (Of course the array bounds should have been discriminants rather than attributes) -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de
From: Jerry on 1 Feb 2010 17:10
I've never understood why Ada does not allow slicing in multidimensional arrays. What are the safety issues involved? And how is it safe to force the programmer into ad hoc methods? Jerry |