From: "Hibou57 (Yannick Duchêne)" <yannick_duchene@yahoo.fr>
Subject: Re: Copying rows in a two dimensional array.
Date: Thu, 4 Feb 2010 01:23:36 -0800 (PST)
Date: 2010-02-04T01:23:36-08:00 [thread overview]
Message-ID: <4cd50297-178c-4172-a2f7-3793675b26ec@h2g2000yqj.googlegroups.com> (raw)
In-Reply-To: 1fmfi9p68s4an$.1q50he325y45g.dlg@40tude.net
On 4 fév, 10:10, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
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 := 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 = First_Index
function Last_Row
(Instance : Instance_Type)
return Index_Type;
function First_Column
(Instance : Instance_Type)
return Index_Type;
--|Ensures: Result = 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) =
--| First_Index + Number_Of_Rows - 1;
--|Ensures:
--| Last_Column (Instance) =
--| First_Index + Number_Of_Column - 1;
--|Ensures:
--| for each Row in First_Row (Instance) .. Last_Row (Instance)
--| => for each Column in First_Column (Instance) ..
--| Last_Column (Instance) => Item (Row, Column) = 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) => (Item (Instance, Row_1, Column) =
--| old Item (Instance, Row_2, Column));
--|Ensures:
--| for each Column in First_Column (Instance) ..
--| Last_Column (Instance) => (Item (Instance, Row_2, Column) =
--| old Item (Instance, Row_1, Column));
-- Note: Row_1 and Row_2 may be equal.
--
===================================================================
-- *** DO NOT CROSS *** DO NOT CROSS *** DO NOT CROSS *** DO NOT
CROSS
--
-------------------------------------------------------------------
private
pragma Assert
((First_Index + (One_Dimensional_Size_Type'Last ** 2)) <=
(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 := 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 := 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 := Start_Of_Row (Instance, Row);
Column_Offset : constant Natural := Column - First_Index;
Data_Index : constant Natural := 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 :=
(Number_Of_Rows * Number_Of_Columns);
Last_Data_Index : constant Natural :=
(First_Index + (Data_Size - 1));
begin
return
(Number_Of_Rows => Number_Of_Rows,
Number_Of_Columns => Number_Of_Columns,
Last_Data_Index => Last_Data_Index,
Data => (others => 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 = Row_2 then
return;
end if;
end Special_Cases;
Method :
declare
-- See comments in the package's private part.
Rows_Size : constant Natural :=
(Instance.Number_Of_Columns);
Slice_Start_Of_Row_1 : constant Natural :=
Start_Of_Row (Instance, Row_1);
Slice_End_Of_Row_1 : constant Natural :=
End_Of_Row (Instance, Row_1);
Slice_Start_Of_Row_2 : constant Natural :=
Start_Of_Row (Instance, Row_1);
Slice_End_Of_Row_2 : constant Natural :=
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) :=
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)
:=
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)
:=
Row_1_Slice;
end Method;
end Swap_Rows; -- Procedure
end Matrix; -- Package
prev parent reply other threads:[~2010-02-04 9:23 UTC|newest]
Thread overview: 48+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-02-01 2:11 Copying rows in a two dimensional array Peter C. Chapin
2010-02-01 4:42 ` Jeffrey R. Carter
2010-02-01 6:55 ` Niklas Holsti
2010-02-01 23:36 ` Peter C. Chapin
2010-02-04 4:27 ` Hibou57 (Yannick Duchêne)
2010-02-01 8:37 ` Dmitry A. Kazakov
2010-02-02 0:11 ` Randy Brukardt
2010-02-07 16:13 ` Robert A Duff
2010-02-08 6:30 ` tmoran
2010-02-08 13:15 ` Robert A Duff
2010-02-08 13:45 ` Dmitry A. Kazakov
2010-02-08 21:20 ` Robert A Duff
2010-02-08 23:26 ` (see below)
2010-02-09 0:36 ` Randy Brukardt
2010-02-09 1:03 ` (see below)
2010-02-09 7:11 ` Pascal Obry
2010-02-09 8:14 ` AdaMagica
2010-02-09 14:33 ` Robert A Duff
2010-02-09 1:05 ` Adam Beneschan
2010-02-09 14:45 ` Robert A Duff
2010-02-09 18:50 ` tmoran
2010-02-09 19:51 ` Pascal Obry
2010-02-09 23:03 ` Robert A Duff
2010-02-08 18:53 ` tmoran
2010-02-08 21:14 ` Robert A Duff
2010-02-08 21:29 ` Pascal Obry
2010-02-09 8:56 ` Jean-Pierre Rosen
2010-02-09 9:14 ` AdaMagica
2010-02-09 11:19 ` Jean-Pierre Rosen
2010-02-09 14:26 ` Robert A Duff
2010-02-09 6:34 ` tmoran
2010-02-09 14:29 ` Robert A Duff
2010-02-09 18:49 ` tmoran
2010-02-09 22:58 ` Robert A Duff
2010-02-01 22:10 ` Jerry
2010-02-02 0:07 ` Randy Brukardt
2010-02-02 8:52 ` Jean-Pierre Rosen
2010-02-02 22:23 ` Jerry
2010-02-03 1:24 ` Adam Beneschan
2010-02-04 4:42 ` Hibou57 (Yannick Duchêne)
2010-02-14 0:42 ` jonathan
2010-02-14 1:54 ` Hibou57 (Yannick Duchêne)
2010-02-14 16:16 ` jonathan
2010-03-22 8:56 ` Ole-Hjalmar Kristensen
2010-02-16 6:51 ` David Thompson
2010-02-04 4:13 ` Hibou57 (Yannick Duchêne)
2010-02-04 9:10 ` Dmitry A. Kazakov
2010-02-04 9:23 ` Hibou57 (Yannick Duchêne) [this message]
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox