From: tmoran@acm.org
Subject: Re: C to Ada conversion
Date: Mon, 13 Jan 2003 23:14:44 GMT
Date: 2003-01-13T23:14:44+00:00 [thread overview]
Message-ID: <ELHU9.51517$%n.18940@sccrnsc02> (raw)
In-Reply-To: a5ae824.0301131322.2c11d495@posting.google.com
> Interested in doing some benchmarking in Ada. ... convert
See below
> I'm also curious on how Ada allocates and deallocates objects
There is an alloc(new)/free mechanism but usually it's more efficient,
as well as easier and less error prone, to just let the compiler allocate
things stack-wise. See matrix "Ac" below. It's allocated automatically,
and deallocated automatically. (Actually, since it's never used here,
one hopes a good compiler doesn't bother generating any code for it.)
procedure Inv is
type Matrices is array (Integer range <>, Integer range <>) of Float;
procedure Matrix_Inversion(A : in out Matrices;
Inverse : out Matrices) is
-- This function inverts a matrix based on the Gauss Jordan method.
-- It raises Constraint_Error if A or Inverse is not square
-- or if their index ranges don't match
-- or if the determinant of A is too small.
-- Note that input matrix A will be modified.
Det : Float := 1.0;
Temp, Pivot, Factor : Float;
Ac : Matrices := A; -- Note: never used, but in C code
begin
Inverse := (others => (others => 0.0));
for I in Inverse'range (1) loop
Inverse(I, I) := 1.0;
end loop;
for iPass in A'range (1) loop
-- For each pass, first find maximum element in the pivot column.
declare
Max_Row : Integer := iPass;
begin
for Row in iPass .. A'Last(1) loop
if abs(A(Row, iPass)) > abs(A(Max_Row, iPass)) then
Max_Row := Row;
end if;
end loop;
-- Interchange the elements of row iPass and Max_Row in both A and Inverse.
if Max_Row /= iPass then
for Col in A'range (2) loop
Temp := Inverse(iPass, Col);
Inverse(iPass, Col) := Inverse(Max_Row, Col);
Inverse(Max_Row, Col) := Temp;
end loop;
end if;
end;
-- The current pivot is now A(iPass, iPass).
-- The determinant is the product of the pivot elements.
Pivot := A(iPass, iPass);
Det := Det * Pivot;
if Det = 0.0 then -- A pointless test in Ada since an
raise Constraint_Error; -- attempted divide by zero will raise
end if; -- Constraint_Error anyway.
-- An erroneous test in C since a very
-- small, but non-zero, Det will not be
-- caught, but will cause divide by zero.
-- Normalize the pivot row by dividing by the pivot element.
for Col in A'range (2) loop
Inverse(iPass, Col) := Inverse(iPass, Col) / Pivot;
if Col >= iPass then
A(iPass, Col) := A(iPass, Col) / Pivot;
end if;
end loop;
-- Add a multiple of the pivot row to each row. The multiple factor
-- is chosen so that the element of A on the pivot column is 0.
for Row in A'range (1) loop
-- Note: this loop had two "if (irow != iPass)" statements,
-- one inside and one outside the column loop. I've combined
-- them for clarity and efficiency
if Row /= iPass then
Factor := A(Row, iPass);
for Col in A'range (2) loop
if Row /= iPass then
Inverse(Row, Col) := Inverse(Row, Col) - Factor * A(iPass, Col);
A(Row, Col) := A(Row, Col) - Factor * A(iPass, Col);
end if;
end loop;
end if;
end loop;
end loop; -- iPass
end Matrix_Inversion;
-- #define ns 30
-- #define ms 12
Rs : constant := 6;
-- A is an n by n matrix, A is the state transistion matrix
-- B is an n by m matrix, B is the input matrix
-- C is an r by n matrix, C is the measurement matrix
-- xhat is an n by 1 vector, xhat is the current state of the system
-- y is an r by 1 vector, y is the measured output of the system
-- u is an m by 1 vector, u is the known input to the system
-- Sz is an r by r matrix, Sz is the measurement nise covariance
-- Sw is an n by n matrix, Sw is the process noise covariance
-- P is an n by n matrix, P is the estimator error covariance
-- float A[ns][ns];
-- float B[ns][ms];
-- float C[rs][ns];
-- float xhat[ns][1];
-- float y[rs][1];
-- float u[ms][1];
-- float Sz[rs][rs];
-- float Sw[ns][ns];
-- float P[ns][ns];
-- float AP[ns][ns]; // This is the matrix A*P
-- float CT[ns][rs]; // This is the matrix CT
-- float APCT[ns][rs]; // This is the matrix A*P*CT
-- float CP[rs][ns]; // This is the matrix C*P
-- float CPCT[rs][rs]; // This is the matrix C*P*CT
CPCTSz : Matrices(1 .. Rs, 1 .. Rs); -- This is the matrix C*P*CT+Sz
CPCTSzInv: Matrices(1 .. Rs, 1 .. Rs); -- (C*P*CT+Sz)**-1
-- float K[ns][rs]; // This is the Kalman gain.
-- float Cxhat[rs][1]; // This is the vector C*xhat
-- float yCxhat[rs][1]; // This is the vector y-C*xhat
-- float KyCxhat[ns][1]; // This is the vector K*(y-C*xhat)
-- float Axhat[ns][1]; // This is the vector A*xhat
-- float Bu[ns][1]; // This is the vector B*u
-- float AxhatBu[ns][1]; // This is the vector A*xhat+B*u
-- float AT[ns][ns]; // This is the matrix AT
-- float APAT[ns][ns]; // This is the matrix A*P*AT
-- float APATSw[ns][ns]; // This is the matrix A*P*AT+Sw
-- float CPAT[rs][ns]; // This is the matrix C*P*AT
-- float SzInv[rs][rs]; // This is the matrix Sz-1
-- float APCTSzInv[ns][rs]; // This is the matrix A*P*CT*Sz-1
-- float APCTSzInvCPAT[ns][ns]; // This is the matrix A*P*CT*Sz-1*C*P*AT
begin
Matrix_Inversion(CPCTSz, CPCTSzInv);
end Inv;
next prev parent reply other threads:[~2003-01-13 23:14 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-01-13 21:22 C to Ada conversion Mark
2003-01-13 23:14 ` tmoran [this message]
2003-01-14 1:27 ` Jeffrey Carter
2003-01-14 3:16 ` tmoran
2003-01-14 12:52 ` Mark
2003-01-14 19:35 ` John R. Strohm
2003-01-14 7:20 ` Martin Dowie
2003-01-14 8:49 ` tmoran
2003-01-14 22:45 ` Martin Dowie
2003-01-14 13:01 ` Mark
2003-01-14 17:18 ` Dr. Michael Paus
2003-01-14 18:10 ` tmoran
2003-01-14 18:24 ` tmoran
2003-01-14 19:48 ` Dr. Michael Paus
2003-01-14 20:12 ` Vinzent Hoefler
2003-01-14 21:55 ` tmoran
2003-01-16 21:17 ` Mark
2003-01-17 0:10 ` tmoran
2003-01-17 1:09 ` John R. Strohm
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox