Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

how to print an array range?

121 views
Skip to first unread message

Nasser M. Abbasi

unread,
Jun 26, 2012, 9:47:01 AM6/26/12
to

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

Georg Bauhaus

unread,
Jun 26, 2012, 9:54:59 AM6/26/12
to
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.

Dmitry A. Kazakov

unread,
Jun 26, 2012, 10:07:07 AM6/26/12
to
On Tue, 26 Jun 2012 08:47:01 -0500, Nasser M. Abbasi wrote:

> simple question from newbie. How do I print array range?

John Woodruff wrote a set of packages for matrix I/O:

http://www.dmitry-kazakov.de/ada/Name_IO_Distribution-Nov10.zip

--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

Nasser M. Abbasi

unread,
Jun 26, 2012, 10:08:44 AM6/26/12
to
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

Nasser M. Abbasi

unread,
Jun 26, 2012, 10:24:30 AM6/26/12
to
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

AdaMagica

unread,
Jun 26, 2012, 11:07:51 AM6/26/12
to n...@12000.org
G.3.1(4/2)
type Real_Vector is array (Integer range <>) of Real'Base;
type Real_Matrix is array (Integer range <>, Integer range <>)o f Real'Base;

So without specifying a range, you get indices starting from Integer'First.

Georg Bauhaus

unread,
Jun 26, 2012, 11:53:20 AM6/26/12
to
On 26.06.12 16:24, Nasser M. Abbasi wrote:
> But I wanted to see the range of
> the first dimension of the Matrix A below. (1..3, 1..3)

Specify the ranges you want, for example,

A : constant Real_Matrix (1 .. 3, 1 .. 3) :=
(( 1.0, 2.0, 3.0),
( 4.0, 5.0, 6.0),
( 7.0, 8.0, 9.0));

or

B : constant Real_Matrix :=
(1 => ( 1.0, 2.0, 3.0),
2 => ( 4.0, 5.0, 6.0),
3 => ( 7.0, 8.0, 9.0));

Nasser M. Abbasi

unread,
Jun 26, 2012, 12:28:21 PM6/26/12
to
On 6/26/2012 10:53 AM, Georg Bauhaus wrote:
> On 26.06.12 16:24, Nasser M. Abbasi wrote:
>> But I wanted to see the range of
>> the first dimension of the Matrix A below. (1..3, 1..3)
>
> Specify the ranges you want, for example,
>
> A : constant Real_Matrix (1 .. 3, 1 .. 3) :=
> (( 1.0, 2.0, 3.0),
> ( 4.0, 5.0, 6.0),
> ( 7.0, 8.0, 9.0));
>

I think I am not explaining myself well.

I simply wanted to print the range itself, after
I define a variable. using PUT().

i.e. in the above, what would one write to
print "1..3" for A'range(1) and "1..3" for A'range(2)?

I am not asking how to specify the range, I know that.
but to print it, for debugging purposes.

I can't just type write put(A'range(1)). And when I write
put(A'first(1)) it prints -2147483648.

Any way, no big deal, will figure it out.

regards,
--Nasser

Georg Bauhaus

unread,
Jun 26, 2012, 12:58:08 PM6/26/12
to
On 26.06.12 18:28, Nasser M. Abbasi wrote:

> I can't just type write put(A'range(1)). And when I write
> put(A'first(1)) it prints -2147483648.

You had got it already, I think. Here is LRM 3.6.2:

7 A'Range A'Range is equivalent to the range A'First .. A'Last,
except that the prefix A is only evaluated once.

Equivalent also means that you can write, in source, A'Range(n)
wherever you could equivalently write A'First(n) .. A'Last(n).
Consider writing

Put (A'First(1) .. A'Last(1));

in source. But this has no meaning as a parameter to Put.

One way is to Put("..") between Put(A'First(1)) and Put(A'Last(1));

John B. Matthews

unread,
Jun 26, 2012, 1:05:06 PM6/26/12
to
In article <jscnv3$9kt$1...@speranza.aioe.org>,
For debugging:

Ada.Text_IO.Put_Line(A'First'Img & " " & A'Last'Img);

Which also sheds light on your previous finding:

B : Real_Matrix(A'Range(1), A'Range(2)); -- correct
B : Real_Matrix(A'Range(1), Integer'First .. Integer'First + 2);

--
John B. Matthews
trashgod at gmail dot com
<http://sites.google.com/site/drjohnbmatthews>

Adam Beneschan

unread,
Jun 26, 2012, 1:15:30 PM6/26/12
to
If you declare A the way Georg described, then put(A'first(1)) should print 1.

I think you may have a fundamental misunderstanding about arrays in Ada; you seem to think that the language automatically "knows", in some way, that the first index of an array is 1. That isn't true. There is no default first index. (This is unlike some languages like C or Java, where the first index is always 0; I don't know what it is in MATLAB.) The first index is whatever you tell the compiler it is. And, as has been pointed out already, if an unconstrained array type is declared with "Integer range <>" as the index, and you set up an aggregate without specifying the first index, the first index will be Integer'first, which is -2147483648 for some Ada compilers (the actual value is compiler-dependent).

So, if you declare

A : constant Real_Matrix :=
(( 1.0, 2.0, 3.0),
( 4.0, 5.0, 6.0),
( 7.0, 8.0, 9.0));

then the first element is at indexes (-2147483648, -2147483648). The last one is at (-2147483646, -2147483646). If you write A(-2147483648, -2147483648) you will get 1.0. If you write A(1,1) you will get a constraint error. A'First(1) and A'First(2) are both -2147483648. A'Last(1) and A'Last(2) are both -2147483646. A'Range(1) is a shorthand for A'First(1)..A'Last(1). If you want something that tells you that the "first index" is 1 and the "last index" is 3, you are not going to get it unless you do the math yourself. (But note that A'Length(1) and A'Length(2) are both 3.) That's also why you're getting the Constraint_Error in your other post. If you say

for I in A'Range(1) loop

then I will take the values -2147483648, -2147483647, -2147483646; and if you use any of those values as an index into B, which has index ranges (1..3, 1..3), you'll get a Constraint_Error, because none of those big negative values is in the range 1..3.

My apologies if I'm hammering on stuff you already know. But it just looked to me that you had a misconception about how array index ranges work in Ada, since you seemed perplexed by some of the results you were getting.

-- Adam

Georg Bauhaus

unread,
Jun 26, 2012, 1:13:42 PM6/26/12
to
On 26.06.12 19:05, John B. Matthews wrote:

> Ada.Text_IO.Put_Line(A'First'Img & " " & A'Last'Img);

In case anyone wishes to write standard Ada when debugging,
not the GNAT language, the implementation specific attribute
'Img can be replaced by standard Ada's

Ada.Text_IO.Put_Line
(Integer'Image(A'First) & " " & Integer'Image(A'Last));

The static member functions of class Integer ;-)

John B. Matthews

unread,
Jun 26, 2012, 3:28:40 PM6/26/12
to
In article <4fe9edc7$0$6570$9b4e...@newsspool4.arcor-online.net>,
Nasser: This is absolutely correct about Ada, and a helpful point of
reference in Java; see also the static member functions of class String.

For more control over width and base, instantiate Integer_IO:

package Ada.Integer_Text_IO is new Ada.Text_IO.Integer_IO (Integer);

An instance of which may already exist in one's library:

with Ada.Integer_Text_IO;

You might also like to compare these two projects that implement the
same root finding algorithm and test program in Ada and Java:

<http://home.roadrunner.com/~jbmatthews/misc/groots.html>
<http://sites.google.com/site/drjohnbmatthews/polyroots>

Robert A Duff

unread,
Jun 26, 2012, 5:31:31 PM6/26/12
to
"Nasser M. Abbasi" <n...@12000.org> writes:

> I know I am doing something silly here.

Or maybe the language designers did something silly.
Why didn't they make the index subtype Positive (or
maybe Natural) instead of Integer? Is it important
to allow negative index values?

- Bob

Dmitry A. Kazakov

unread,
Jun 26, 2012, 6:17:13 PM6/26/12
to
On Tue, 26 Jun 2012 17:31:31 -0400, Robert A Duff wrote:

> Why didn't they make the index subtype Positive (or
> maybe Natural) instead of Integer?

Why should they limit index to a subset which would have more problems with
not being closed upon arithmetic operations than Integer? The only real
constraint here is the array bounds. Ideally index should be
Universal_Integer.

> Is it important to allow negative index values?

Yes, there were several cases I used a negative lower bound.

One important case is when you have a n-elements thick border around the
original matrix filled with some special values, usually zeros. This
technique is used when matrix elements are convoluted. E.g. let you compute
something like diagonal sums like:

A(I - 2, J) + A(I - 1, J) + A (I, J) + A (I + 1, J) + A (I + 2, J)

You don't want to check I for special border cases A'First (1), A'First (1)
+ 1, A'Last (1) - 1, A'Last (1). Instead of that you add a border of zeros,
trading a little space for index checks, and get more uniform and efficient
code.
Message has been deleted

Randy Brukardt

unread,
Jun 26, 2012, 6:39:08 PM6/26/12
to
"Robert A Duff" <bob...@shell01.TheWorld.com> wrote in message
news:wccvcid...@shell01.TheWorld.com...
Well, it wasn't the language designers; we got those packages almost
unmodified from a previous standard. And we did talk about changing Matrix
to have a range of Positive, but I believe there were some examples shown of
negative indexes making sense. So in the end, we didn't change something
that others had designed, presumably for a reason.

Randy.


Jeffrey Carter

unread,
Jun 26, 2012, 7:13:47 PM6/26/12
to
On 06/26/2012 03:30 PM, Dennis Lee Bieber wrote:
>>
> It could simplify the mapping of real-world coordinates to a scaled
> integer coordinate frame when negative coordinates are permitted.

The type in question, Real_Matrix, is intended to model mathematical matrices,
not to be a general-purpose array. The only definitions I've seen of
mathematical matrices look like

An MxN matrix X is defined as

+- -+
|x(1,1) x(1,2) ... x(1,N)|
X = |x(2,1) x(2,2) ... x(2,N)|
|... |
|x(M,1) x(M,2) ... x(M,N)|
+- -+

except the indices are subscript, not in parentheses. In other words, a lower
bound of 1 is part of the definition of a matrix.

Of course, I'm not a mathematician, so I might be mistaken.

--
Jeff Carter
"People called Romanes, they go the house?"
Monty Python's Life of Brian
79



--- Posted via news://freenews.netfront.net/ - Complaints to ne...@netfront.net ---

Jacob Sparre Andersen

unread,
Jun 27, 2012, 2:58:24 AM6/27/12
to
Jeffrey Carter wrote:

> The type in question, Real_Matrix, is intended to model mathematical
> matrices, not to be a general-purpose array.

Yes. But that shouldn't keep us from having a better solution than the
conventional one. Allowing matrices with indexes symmetric around 0
means that you can solve some problems with out having to keep track of
$M_{i-2,j+2}$ (or was it $j-2$) as we have to in symbolic mathematics.

> Of course, I'm not a mathematician, so I might be mistaken.

As a mathematician (or maybe it is really as a physicist), I'm quite
happy with the extra expressiveness of the Ada matrix packages.

Greetings,

Jacob
--
"Sleep is just a cheap substitute for coffee"

Shark8

unread,
Jun 28, 2012, 2:59:39 AM6/28/12
to n...@12000.org
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.}
0 new messages