Previous Table of Contents Next


10.4.2.8. Using the Generic Matrix Package

Before examining the implementation of HB.Matrices_Generic, see how it might be used. Show_Matrices is a sample client in which the matrix element type is Rational.

    1 with Ada.Text_IO; use Ada.Text_IO;
    2 with HB.Rationals; use HB.Rationals;
    3 with HB.Rationals.IO; use HB.Rationals.IO;
    4 with HB.Matrices_Generic;
    5 procedure Show_Matrices is
    6
    7   package Rational_Matrices is new HB.Matrices_Generic
    8     (ElementType => Rational,
    9      Zero        => 0/1,
   10      Unity       => 1/1,
   11      “+” => HB.Rationals.”+”,
   12      “*” => HB.Rationals.”*”);
   13   use Rational_Matrices;
   14
   15   procedure Put(Item: in Vector) is
   16   begin
   17     for Element in Item’Range loop
   18       Put(Item(Element));
   19       Put(“  “);
   20     end loop;
   21     New_Line(Spacing => 2);
   22   end Put;
   23
   24   procedure Put(Item: in Matrix) is
   25   begin
   26     for Row in Item’Range(1) loop
   27       for Col in Item’Range(2) loop
   28         Put(Item(Row, Col));
   29         Put(“  “);
   30       end loop;
   31       New_Line;
   32     end loop;
   33     New_Line;
   34   end Put;
   35
   36   V: Vector(1..3) := (1/3, 2/3, 0/1);
   37   M: Matrix(1..3, 1..4) := ((0/1, 1/3, 1/2, 1/4),
   38                           (1/1, 1/2, 1/2, 0/1),
   39                           (1/4, 2/3, 1/4, 1/5));
   40
   41 begin
   42
   43   Put_Line(“V =”); Put(V);
   44   Put_Line(“M =”); Put(M);
   45   Put_Line(“1/2 * M =”); Put(1/2 * M);
   46   Put_Line(“V * M =”); Put(V * M);
   47
   48   begin
   49     Put_Line(“M * V =”); Put(M * V);
   50     Put_Line(“Exception should have been raised”);
   51   exception
   52     when Bounds_Error =>
   53       Put_Line(“Exception properly raised”);
   54   end;
   55
   56 end Show_Matrices;

This program is in “terse” style with use clauses supplied and named parameters used only where extra clarity is needed. Lines 7-12 create an instance Rational_Matrices of the generic template. In line 11, the association

   “+” => HB.Rationals.”+”

is written verbosely, just for clarity’s sake. Indeed, the instantiation could have been written (tersely but more opaquely) as

   package Rational_Matrices is
     new HB.Matrices_Generic (Rational, 0/1, 1/1, “+”, “*”);

The instance is now a use-able package, so I can supply a use clause (line 13). This instance gives me the types Rational_Matrices.Vector and Rational_Matrices.Matrix; the use lets me refer to these just as Vector and Matrix.

Lines 15-22 is a procedure to display the elements of a vector. There is nothing new here except (line 21) the use of the Spacing parameter to New_Line, which has the obvious meaning of “move the cursor to the next line and then move it again.”

Lines 24-34 show a procedure to display a matrix, row-by-row. Note in line 26 the attribute Item’Range(1), which means “the range of Item’s first dimension,” and in line 27, the attribute Item’Range(2), which means “the range of Item’s second dimension.” Here again you see the power of attributes to work with arrays whose bounds are unknown at compilation time.

Lines 36-39 declare a vector and matrix, both initialized with aggregates of rational quantities. The 2D aggregate initializes M row-by-row. Lines 43-46 display the vector and the matrix, followed by the matrix scaled by 1/2 and then by the product of the vector and the matrix.

Lines 48-54 are used to illustrate a frame style that is commonly used in writing a program designed to test a package. The product M*V is mathematically impossible because M has 4 columns, but there, column vector V has only 3 columns. Bounds_Error is raised to signal this abstraction violation, if and only if the product operation is correctly implemented in the package.

The actual output of this program should be

   V =
   1/3  2/3  0/1

   M =
   0/1  1/3  1/2  1/4
   1/1  1/2  1/2  0/1
   1/4  2/3  1/4  1/5

   1/2 * M =
   0/2  1/6  1/4  1/8
   1/2  1/4  1/4  0/2
   1/8  2/6  1/8  1/10

   V * M =
   24/36  72/162  72/144  15/180

   M * V =
   Exception properly raised


Previous Table of Contents Next