From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: a07f3367d7,bf03d731a6ef511f X-Google-Attributes: gida07f3367d7,public,usenet X-Google-NewGroupId: yes X-Google-Language: ENGLISH,ASCII Path: g2news1.google.com!postnews.google.com!h2g2000yqj.googlegroups.com!not-for-mail From: =?ISO-8859-1?Q?Hibou57_=28Yannick_Duch=EAne=29?= Newsgroups: comp.lang.ada Subject: Re: Copying rows in a two dimensional array. Date: Thu, 4 Feb 2010 01:23:36 -0800 (PST) Organization: http://groups.google.com Message-ID: <4cd50297-178c-4172-a2f7-3793675b26ec@h2g2000yqj.googlegroups.com> References: <4b6637a1$0$4586$4d3efbfe@news.sover.net> <1fmfi9p68s4an$.1q50he325y45g.dlg@40tude.net> NNTP-Posting-Host: 86.66.190.223 Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable X-Trace: posting.google.com 1265275416 18185 127.0.0.1 (4 Feb 2010 09:23:36 GMT) X-Complaints-To: groups-abuse@google.com NNTP-Posting-Date: Thu, 4 Feb 2010 09:23:36 +0000 (UTC) Complaints-To: groups-abuse@google.com Injection-Info: h2g2000yqj.googlegroups.com; posting-host=86.66.190.223; posting-account=vrfdLAoAAAAauX_3XwyXEwXCWN3A1l8D User-Agent: G2/1.0 X-HTTP-UserAgent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; fr),gzip(gfe),gzip(gfe) Xref: g2news1.google.com comp.lang.ada:8879 Date: 2010-02-04T01:23:36-08:00 List-Id: On 4 f=E9v, 10:10, "Dmitry A. Kazakov" wrote: > This does not work either, I mean at the user interface level, because > slice does not have a type. In Ada types system you cannot express "the > subtype S is a vector of the type M". Therefore making it abstract types > you will loose most of the comfort built-in arrays offer. I've was to post him some seed of a package (not tested, I sincerely apologize for that) : package Matrix is -- Provides a matrix type with an efficient implementation -- of a row swapping method. A similar method as the one -- provided here, may be used to get a matrix type with an -- efficient implementation of column swapping method. -- This package most likely need to be extended in order -- to be fully useful to something in real life. subtype Float_Type is Float; subtype One_Dimensional_Size_Type is Natural range 1 .. 2 ** 15; -- Either a number of rows or a number of columns. -- The maximum size is so that One_Dimensional_Size_Type ** 2 is -- most unlikely to commit an overflow and will mostly be a valid -- value on most of target machines. First_Index : constant :=3D 1; -- This may be changed to zero if needed, whenever the -- C indexing convention is preferred. This may not be -- changed to a value greater than one, otherwise -- Index_Type may potentially go out of Natural range. subtype Index_Type is Natural range (First_Index) .. (First_Index + (One_Dimensional_Size_Type'Last - 1)); type Instance_Type (<>) is private; -- The type must be initialized at declaration : -- use New_Instance in that purpose (see below). -- The methods First_Row, Last_Row, First_Column, -- Last_Column and Item, are at least required to -- define pre- and post- condition of the New_Instance -- and Swap_Rows method. function First_Row (Instance : Instance_Type) return Index_Type; --|Ensures: Result =3D First_Index function Last_Row (Instance : Instance_Type) return Index_Type; function First_Column (Instance : Instance_Type) return Index_Type; --|Ensures: Result =3D First_Index function Last_Column (Instance : Instance_Type) return Index_Type; function Item (Instance : Instance_Type; Row : Index_Type; Column : Index_Type) return Float_Type; --|Requires: Row in First_Row (Instance) .. Last_Row (Instance); --|Requires: --| Column in First_Column (Instance) .. --| Last_Column (Instance); function New_Instance (Number_Of_Rows : One_Dimensional_Size_Type; Number_Of_Columns : One_Dimensional_Size_Type) return Instance_Type; --|Ensures: --| Last_Row (Instance) =3D --| First_Index + Number_Of_Rows - 1; --|Ensures: --| Last_Column (Instance) =3D --| First_Index + Number_Of_Column - 1; --|Ensures: --| for each Row in First_Row (Instance) .. Last_Row (Instance) --| =3D> for each Column in First_Column (Instance) .. --| Last_Column (Instance) =3D> Item (Row, Column) =3D 0.0; -- Note : all items are zero initialized. procedure Swap_Rows (Instance : in out Instance_Type; Row_1 : in Index_Type; Row_2 : in Index_Type); --|Requires: Row_1 in First_Row (Instance) .. Last_Row (Instance); --|Requires: Row_2 in First_Row (Instance) .. Last_Row (Instance); --|Ensures: --| for each Column in First_Column (Instance) .. --| Last_Column (Instance) =3D> (Item (Instance, Row_1, Column) =3D --| old Item (Instance, Row_2, Column)); --|Ensures: --| for each Column in First_Column (Instance) .. --| Last_Column (Instance) =3D> (Item (Instance, Row_2, Column) =3D --| old Item (Instance, Row_1, Column)); -- Note: Row_1 and Row_2 may be equal. -- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -- *** DO NOT CROSS *** DO NOT CROSS *** DO NOT CROSS *** DO NOT CROSS -- ------------------------------------------------------------------- private pragma Assert ((First_Index + (One_Dimensional_Size_Type'Last ** 2)) <=3D (Natural'Last)); -- Ensure computation on indexes will never go out of range. pragma Inline (First_Row); pragma Inline (Last_Row); pragma Inline (First_Column); pragma Inline (Last_Column); type Storage_Type is array (Natural range <>) of Float_Type; -- Flatenned array rows first columns next. -- Ex. (Row-1,Col-1),(Row-2,Col-1),(Row-1,Col-2),(Row-2,Col-2) -- -- This way of flatening the matrix is the one which gives -- better performance to swap rows, as all items of a row -- appears to be consecutive, allowing slice access. -- -- If good performance at swaping columns is targeting instead, -- then use the reverse representation (that is, like the -- Fortran convention), and update implementation of methods -- accordingly. -- -- Note: the index type musn't be Index_Type, -- which is an index in one dimension, not in the overall storage. type Instance_Type (Number_Of_Rows : One_Dimensional_Size_Type; Number_Of_Columns : One_Dimensional_Size_Type; Last_Data_Index : Natural) is record Data : Storage_Type (First_Index .. Last_Data_Index); end record; end Matrix; package body Matrix is function First_Row (Instance : Instance_Type) return Index_Type is begin return First_Index; end First_Row; function Last_Row (Instance : Instance_Type) return Index_Type is begin return First_Index + (Instance.Number_Of_Rows - 1); end Last_Row; function First_Column (Instance : Instance_Type) return Index_Type is begin return First_Index; end First_Column; function Last_Column (Instance : Instance_Type) return Index_Type is begin return First_Index + (Instance.Number_Of_Columns - 1); end Last_Column; function Start_Of_Row (Instance : Instance_Type; Row : Index_Type) return Natural -- Index in Data for the first item of the row -- whose index is Row. Used for accessing a matrix items -- and for row slice accesses. is Rows_Size : constant Natural :=3D Instance.Number_Of_Columns; begin return First_Index + (Rows_Size * (Row - First_Index)); end Start_Of_Row; pragma Inline (Start_Of_Row); function End_Of_Row (Instance : Instance_Type; Row : Index_Type) return Natural -- Index in Data for the last item of the row -- whose index is Row. Used for row slice accesses. is Rows_Size : constant Natural :=3D Instance.Number_Of_Columns; begin return Start_Of_Row (Instance, Row) + (Rows_Size - 1); -- This is an upper bound, not a limit, so -- Rows_Size - 1 is used. We add an offset starting -- the fist index of the row. end End_Of_Row; pragma Inline (End_Of_Row); function Item (Instance : Instance_Type; Row : Index_Type; Column : Index_Type) return Float_Type is begin Validity_Constraints : begin if Row not in First_Index .. Last_Row (Instance) then raise Program_Error; end if; if Column not in First_Index .. Last_Column (Instance) then raise Program_Error; end if; end Validity_Constraints; Method: declare Row_Start : constant Natural :=3D Start_Of_Row (Instance, Row); Column_Offset : constant Natural :=3D Column - First_Index; Data_Index : constant Natural :=3D Row_Start + Column_Offset; begin return Instance.Data (Data_Index); end Method; end Item; -- Procedure function New_Instance (Number_Of_Rows : One_Dimensional_Size_Type; Number_Of_Columns : One_Dimensional_Size_Type) return Instance_Type is Data_Size : constant Natural :=3D (Number_Of_Rows * Number_Of_Columns); Last_Data_Index : constant Natural :=3D (First_Index + (Data_Size - 1)); begin return (Number_Of_Rows =3D> Number_Of_Rows, Number_Of_Columns =3D> Number_Of_Columns, Last_Data_Index =3D> Last_Data_Index, Data =3D> (others =3D> 0.0)); end New_Instance; -- Function procedure Swap_Rows (Instance : in out Instance_Type; Row_1 : in Index_Type; Row_2 : in Index_Type) is begin Validity_Constraints : begin if Row_1 not in First_Index .. Last_Row (Instance) then raise Program_Error; end if; if Row_2 not in First_Index .. Last_Row (Instance) then raise Program_Error; end if; end Validity_Constraints; Special_Cases : begin if Row_1 =3D Row_2 then return; end if; end Special_Cases; Method : declare -- See comments in the package's private part. Rows_Size : constant Natural :=3D (Instance.Number_Of_Columns); Slice_Start_Of_Row_1 : constant Natural :=3D Start_Of_Row (Instance, Row_1); Slice_End_Of_Row_1 : constant Natural :=3D End_Of_Row (Instance, Row_1); Slice_Start_Of_Row_2 : constant Natural :=3D Start_Of_Row (Instance, Row_1); Slice_End_Of_Row_2 : constant Natural :=3D End_Of_Row (Instance, Row_2); Row_1_Slice : constant Storage_Type -- Backup of Row-1 (Slice_Start_Of_Row_1 .. Slice_End_Of_Row_1) :=3D Instance.Data (Slice_Start_Of_Row_1 .. Slice_End_Of_Row_1); begin -- Copy Row-2 at the place of Row-1 (Row-1 was -- backed up). Instance.Data (Slice_Start_Of_Row_1 .. Slice_End_Of_Row_1) :=3D Instance.Data (Slice_Start_Of_Row_2 .. Slice_End_Of_Row_2); -- Copy backup of Row-1 at the place of -- Row-2. Instance.Data (Slice_Start_Of_Row_2 .. Slice_End_Of_Row_2) :=3D Row_1_Slice; end Method; end Swap_Rows; -- Procedure end Matrix; -- Package