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

tableau à 2 dimensions

60 views
Skip to first unread message

letocha

unread,
Jan 8, 2013, 3:56:14 PM1/8/13
to
bonjour,

Je voudrais un tableau à 2 dimensions,
sans passer par le type array mais avec les containers.

J'ai donc commencer par le type vectors,
et puis j'ai fait un vector de vector.

Je précise que les dimensions seront fixes.

Est-ce que c'est la meilleure façon ?

merci.

Ludovic Brenta

unread,
Jan 8, 2013, 4:36:42 PM1/8/13
to
Pourquoi pas un simple array si les dimensions sont fixes?

Le problème avec un vector de vectors est l'absence de garantie que tous
les vecteurs de second niveau aient la même longueur. Un simple array
apporte cette garantie. Et, avant Ada 2012, c'est plus difficile à
programmer et moins lisible.

Maintenant, s'il s'agit de modéliser une matrice creuse potentiellement
très grande, quelque chose de plus sophistiqué est nécessaire.

--
Ludovic Brenta.

letocha

unread,
Jan 9, 2013, 1:50:14 PM1/9/13
to
j'avais des stacks overflow avec mon array
(dimension 2000 par 1000, dont chaque élement est une liste de plusieurs centaines d'entier)
j'utilise ada2012

Je me posais aussi la question, finalement je peux avoir un simple vector,
dont la taille est égale à celle du produit d'un tableau à 2 dimension,
j'accède aux élements de second niveau par un calcul sur le reste de la division...
Finalement le fait de pouvoir définir des tableaux de plusieurs dimensions avevc array est un simple raccourci pratique. non ?

Ludovic Brenta

unread,
Jan 9, 2013, 3:42:45 PM1/9/13
to
letocha writes on fr.comp.lang.ada:
> j'avais des stacks overflow avec mon array (dimension 2000 par 1000,
> dont chaque élement est une liste de plusieurs centaines d'entier)

Donc, en réalité, un tableau à 3 dimensions :)

Il "suffit" de ne pas déclarer un tel tableau sur la pile (stack):

type Three_Dimension_Array is
array (Positive range <>, Positive range <>, Positive range <>) of Integer;
type Three_Dimension_Array_Access is access Three_Dimension_Array;
procedure Free is new Ada.Unchecked_Deallocation
(Three_Dimension_Array, Three_Dimension_Array_Access);

...

declare
A : Three_Dimension_Array (1000, 2000, 800); -- stack overflow
B : Three_Dimension_Array_Access :=
new Three_Dimension_Array (2000, 1000, 800); -- OK
begin
...
Free (B);
end;

> j'utilise ada2012

Bien: cela permet d'utiliser des Vector avec la même syntaxe que les arrays.

> Je me posais aussi la question, finalement je peux avoir un simple
> vector, dont la taille est égale à celle du produit d'un tableau à 2
> dimension, j'accède aux élements de second niveau par un calcul sur le
> reste de la division...

Mauvaise idée (à mon humble avis). Les trois dimensions n'ont-elles des
types différents? Avec les calculs à la volée, le mélange des types est
une source d'erreurs humaines très difficiles à découvrir, surtout dans
un très grand tableau.

> Finalement le fait de pouvoir définir des tableaux de plusieurs
> dimensions avevc array est un simple raccourci pratique. non ?

Non. Les Vector sont contrôlés, beaucoup plus complexes et moins
efficaces. Cependant, si le tableau à 3 dimensions est creux (beaucoup
de zéros), une représentation plus complexe peut devenir plus efficace,
par exemple avec des B-Trees ou des Vector de paires { indice, valeur }.

--
Ludovic Brenta.

letocha

unread,
Jan 10, 2013, 5:25:29 AM1/10/13
to
parfait !

letocha

unread,
Jan 10, 2013, 9:40:04 AM1/10/13
to
>Bien: cela permet d'utiliser des Vector avec la même syntaxe que les arrays.

Par contre, je ne comprends pas ce point.

Ludovic Brenta

unread,
Jan 10, 2013, 4:56:49 PM1/10/13
to
letocha writes:
>> Bien: cela permet d'utiliser des Vector avec la même syntaxe que les arrays.
>
> Par contre, je ne comprends pas ce point.

Les explications ici:

http://www.adacore.com/adaanswers/gems/gem-123-implicit-dereferencing-in-ada-2012/

et les détails ici:

http://www.ada-auth.org/standards/12rm/html/RM-A-18-2.html

clauses 147.5/3 et suivantes.

En supposant ceci:

package Vectors is new
Ada.Containers.Vectors (Index_Type => Positive,
Element_Type => Integer);
V : Vectors.Vector;
begin
V.Append (12); -- ou bien: Vectors.Append (V, 12);

en Ada 2005 il fallait écrire:

Ada.Integer_Text_IO.Put (V.Element (1)); -- ou bien: Vectors.Element (V, 1)
V.Replace_Element (1, 42); -- ou bien: Vectors.Replace_Element (V, 1, 42)

mais Ada 2012 permet d'écrire:

Ada.Integer_Text_IO.Put (V (1));
V (1) := 42;

donc, comme pour un tableau à une dimension. Pour des vectors de
vectors de vectors, la syntaxe serait:

V (1) (2) (3) := 42;

et non pas

T (1, 2, 3) := 42;

pour un tableau.

--
Ludovic Brenta.

letocha

unread,
Jan 11, 2013, 8:52:19 AM1/11/13
to
Ok, en effet malgré ma lecture - certainement trop distraite - des RM2012, j'avais pas vu cette possibilité de faire un V(1):= avec un Vector.

J-P. Rosen

unread,
Jan 11, 2013, 11:52:35 AM1/11/13
to
Le 11/01/2013 14:52, letocha a écrit :
> Ok, en effet malgré ma lecture - certainement trop distraite - des
> RM2012, j'avais pas vu cette possibilité de faire un V(1):= avec un
> Vector.
Ce qui montre à ceux qui ne seraient pas encore au courant que le RM
n'est absolument pas le bon moyen d'apprendre le langage!

En effet, c'est quasi-impossible à deviner, mais bien expliqué dans le
Rational.

--
J-P. Rosen
Adalog
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52, Fax: +33 1 45 29 25 00
http://www.adalog.fr

letocha

unread,
Jan 11, 2013, 3:02:11 PM1/11/13
to
le Rational et....ada.comp.lang.fr !

Georg Bauhaus

unread,
Jan 15, 2013, 7:37:01 AM1/15/13
to
On 09.01.13 21:42, Ludovic Brenta wrote:
> Il "suffit" de ne pas déclarer un tel tableau sur la pile (stack):

It "suffit" de choisir un compilateur Ada ! ;-) Ce problème est la
consequence de GCC et du pile quantifié (4KiB), n'est pas?

Qu'est ce qu'on fait dans le cas suivant, quand on utilise GNAT :

pragma Restrictions (No_Accocators) ?


-- Georg

Ludovic Brenta

unread,
Jan 15, 2013, 3:14:06 PM1/15/13
to
Georg Bauhaus <rm.dash...@futureapps.de> writes:
> On 09.01.13 21:42, Ludovic Brenta wrote:
>> Il "suffit" de ne pas déclarer un tel tableau sur la pile (stack):
>
> It "suffit" de choisir un compilateur Ada ! ;-) Ce problème est la
> consequence de GCC et du pile quantifié (4KiB), n'est pas?

La taille de la pile dépend non seulement du compilateur mais aussi de
la machine cible. Je ne sais pas quelle machine cible limite la taille
à 4 kiB. En tout cas, il ne faut jamais présumer que la pile est
infinie, surtout dans des tâches autres que la tâche d'environnement.

> Qu'est ce qu'on fait dans le cas suivant, quand on utilise GNAT :
>
> pragma Restrictions (No_Accocators) ?

On crée un tableau statique:

package Globals is
pragma Preelaborate;
type T is digits ... range ...;
type Matrix is array (Positive range <>,
Positive range <>,
Positive range <>) of T;

M : Matrix (1 .. 1000, 1 .. 2000, 1 .. 100);
end Globals;

(ce qui est la norme en avionique et autres domaines à haute intégrité)

--
Ludovic Brenta;

Georg Bauhaus

unread,
Jan 16, 2013, 7:08:01 AM1/16/13
to
On 15.01.13 21:14, Ludovic Brenta wrote:
>> Qu'est ce qu'on fait dans le cas suivant, quand on utilise GNAT :
>> >
>> > pragma Restrictions (No_Accocators) ?
> On crée un tableau statique:

Il me semble que ce n'est pas practique :

pragma Restrictions (No_Allocators);

with Ada.Numerics.Generic_Real_Arrays;

package Globals is
pragma Preelaborate (Globals);
type T is digits 6;
package Linalg is new
Ada.Numerics.Generic_Real_Arrays (T);

subtype Carré is
Linalg.Real_Matrix (1 .. 20_000, 1 .. 20_000);

M1, M2, Résultat : Carré;
end Globals;

with Globals;

procedure Run_Using_Globals is
use Globals;
use type Carré;
begin
Résultat := M1 * M2; -- "*" de la bibliothèque
end Run_Using_Globals;


$ ~/News/run_using_globals

raised STORAGE_ERROR : stack overflow
$

(Aucune réponse après de compiler avec -O.)


Alors, si on veut déclarer des objets, euh, grands,
et si le compilateur est GNAT, il faut être attentif !


--
Georg Bauhaus

Blady

unread,
Feb 27, 2013, 5:11:40 AM2/27/13
to
Le 16/01/13 13:08, Georg Bauhaus a écrit :
Bonjour, rapide essai avec GNAT GPL 2012 sur MacOS 10.8,
il y a un crash de 'as' sur la taille des matrices :

$ gnatmake -gnatW8 run_using_globals
gcc -c -gnatW8 globals.ads
as: fatal error in /usr/bin/../libexec/as/x86_64/as
gnatmake: "globals.ads" compilation error

Évidemment, si je diminue la taille :

$ cat globals.ads
with Ada.Numerics.Generic_Real_Arrays;
package Globals is
pragma Preelaborate (Globals);
type T is digits 6;
package Linalg is new
Ada.Numerics.Generic_Real_Arrays (T);

subtype Carré is
-- Linalg.Real_Matrix (1 .. 20_000, 1 .. 20_000);
Linalg.Real_Matrix (1 .. 20, 1 .. 20);

M1, M2, Résultat : Carré;
end Globals;

$ gnatmake -gnatW8 run_using_globals
gcc -c -gnatW8 run_using_globals.adb
gcc -c -gnatW8 globals.ads
gnatbind -x run_using_globals.ali
gnatlink run_using_globals.ali

Cela dépend-t-il d'un paramètre système ? Modifiable ?

Pascal.
http://blady.pagesperso-orange.fr


Georg Bauhaus

unread,
Mar 2, 2013, 7:22:30 AM3/2/13
to
On 27.02.13 11:11, Blady wrote:
> Le 16/01/13 13:08, Georg Bauhaus a écrit :
>> with Ada.Numerics.Generic_Real_Arrays;
>>
>> package Globals is
>> pragma Preelaborate (Globals);
>> type T is digits 6;
>> package Linalg is new
>> Ada.Numerics.Generic_Real_Arrays (T);
>>
>> subtype Carré is
>> Linalg.Real_Matrix (1 .. 20_000, 1 .. 20_000);
>>
>> M1, M2, Résultat : Carré;
>> end Globals;
>>
>> with Globals;

> Bonjour, rapide essai avec GNAT GPL 2012 sur MacOS 10.8,
> il y a un crash de 'as' sur la taille des matrices :

GNAT 2012 sur MacOS 10.7 et le même crash de 'as'.
L'erreur a disparu des GNATs récents :

GNATMAKE 4.8.0 20130212 (experimental) [trunk revision 195968]
Copyright (C) 1995-2013, Free Software Foundation, Inc.
"run_using_globals.ali" being checked ...
-> "globals.ads" time stamp mismatch
gcc -c -gnatW8 -gnatwa -fstack-check -gnato run_using_globals.adb
"globals.ali" being checked ...
-> "globals.ads" time stamp mismatch
gcc -c -gnatW8 -gnatwa -fstack-check -gnato globals.ads
End of compilation
gnatbind -x run_using_globals.ali
gnatlink run_using_globals.ali -fstack-check
$

Le programme se termine par un message d'erreur,
$ ./run_using_globals

raised STORAGE_ERROR : stack overflow
$

Selon
http://developer.apple.com/library/mac/#qa/qa1419/_index.html
le taille maximale d'une pile est "64 Megabytes".


> Cela dépend-t-il d'un paramètre système ? Modifiable ?

$ ulimit -s { nombre | "hard" }

ajuste la taille de la pile de lenvironment task.
Pour voir les limites actuelles et extrêmes,


with Sys_Resource_H; -- g++ -c -fdump-ada-spec -C ; gcc -gnat05 *.ads
-- et annuler l'effet de __DARWIN_ALIAS (?) ("_")
with Interfaces.C.Strings;
with Ada.Text_IO;

procedure Defaults_Mac is
use Sys_Resource_H, Ada.Text_IO, Interfaces;
package Size_IO is new Modular_IO (rlim_t);
procedure perror (S : C.Strings.chars_ptr);
pragma Import (C, perror);

RLIMIT_CPU : constant := 0;
RLIMIT_FSIZE : constant := 1;
RLIMIT_DATA : constant := 2;
RLIMIT_STACK : constant := 3;
RLIMIT_CORE : constant := 4;
RLIMIT_AS : constant := 5;
RLIMIT_RSS : constant := RLIMIT_AS;
RLIMIT_MEMLOCK : constant := 6;
RLIMIT_NPROC : constant := 7;
RLIMIT_NOFILE : constant := 8;

subtype Resource_Limit is C.int range RLIMIT_CPU .. RLIMIT_NOFILE;
use type Resource_Limit;

subtype Etiquette is String (1 .. 7);
type Apparence is record
Nom : Etiquette;
Echelle : rlim_t;
Unité : Character;
end record;
Info : constant array (Resource_Limit) of Apparence :=
(RLIMIT_CPU => ("CPU" & " ", 1, 's'),
RLIMIT_FSIZE => ("FSIZE" & " ", 1, '#'),
RLIMIT_DATA => ("DATA" & " ", 1024, 'k'),
RLIMIT_STACK => ("STACK" & " ", 1024, 'k'),
RLIMIT_CORE => ("CORE" & " ", 1, '#'),
RLIMIT_RSS => ("RSS" & " ", 1024, 'k'),
RLIMIT_MEMLOCK => ("MEMLOCK" & "", 1024, 'k'),
RLIMIT_NPROC => ("NPROC" & " ", 1, '#'),
RLIMIT_NOFILE => ("NOFILE" & " ", 1, '#'));

L : aliased rlimit;

procedure Montrer (R : Resource_Limit) is
--# global in L;
I : Apparence renames Info (R);
use type rlim_t;
begin
Put (I.Nom & ": ");
Size_IO.Put (L.rlim_cur / I.Echelle);
Put (' ' & I.Unité);
Size_IO.Put (L.rlim_max / I.Echelle);
Put (' ' & I.Unité);
New_Line;
end Montrer;

begin
for R in Resource_Limit loop
if 0 = getrlimit (R, L'access) then
Montrer (R);
else
perror(C.Strings.New_String
("limite n°" & Resource_Limit'Image (R)));
end if;
end loop;
end Defaults_Mac;

Blady

unread,
Mar 6, 2013, 4:00:13 PM3/6/13
to
Bonne nouvelle, j'espère que cela sera aussi le cas pour le prochain
GNAT GPL 2013.

Au passage j'ai remplacé "with Sys_Resource_H" par :
-- typedef __uint64_t rlim_t;
-- struct rlimit {
-- rlim_t rlim_cur; /* current (soft) limit */
-- rlim_t rlim_max; /* hard limit */
-- };
subtype rlim_t is interfaces.Unsigned_64;
type rlimit is record
rlim_cur : rlim_t;
rlim_max : rlim_t;
end record;
pragma Convention (C, rlimit);
-- int getrlimit(int resource, struct rlimit *rlp);
function getrlimit (resource:Interfaces.c.int; rlp:access
rlimit)return Interfaces.c.int;
pragma Import (C, getrlimit);

Cela donne effectivement 64 Mo pour la taille max de pile.

$ ./defaults_mac
CPU : 9223372036854775807 s 9223372036854775807 s
FSIZE : 9223372036854775807 # 9223372036854775807 #
DATA : 9007199254740991 k 9007199254740991 k
STACK : 8192 k 65532 k
CORE : 0 # 9223372036854775807 #
RSS : 9007199254740991 k 9007199254740991 k
MEMLOCK: 9007199254740991 k 9007199254740991 k
NPROC : 709 # 1064 #
NOFILE : 256 # 9223372036854775807 #

Cependant reste que les déclarations M1 (...) de globals.ads ne sont pas
faites à priori sur la pile !?
Le message "stack overflow" est sans doute une source de confusion.

Pascal.
http://blady.pagesperso-orange.fr

Le 02/03/13 13:22, Georg Bauhaus a écrit :
> On 27.02.13 11:11, Blady wrote:
>> Le 16/01/13 13:08, Georg Bauhaus a écrit :
...
0 new messages