Using the existing definition, we'd have to first convert a complex vector
to a real one by computing the modulus ("abs") of each element. Constructing
an extra temporary vector is inefficient and may use an unexpected amount
of extra storage. No change in behavior for the real case though, this just
prepares for subsequent use in the Generic_Complex_Arrays package.

Tested on x86_64-pc-linux-gnu, committed on trunk

2011-10-13  Geert Bosch  <bo...@adacore.com>

        * a-ngrear.adb ("abs"): Adjust for modified L2_Norm generic
        * s-gearop.ads (L2_Norm): Change profile to be suitable for
        Complex_Vector
        * s-gearop.adb (L2_Norm): Reimplement using direct definition,
        not inner product

Index: a-ngrear.adb
===================================================================
--- a-ngrear.adb        (revision 179894)
+++ a-ngrear.adb        (working copy)
@@ -356,10 +356,14 @@
 
       function "abs" is new
         L2_Norm
-          (Scalar        => Real'Base,
-           Vector        => Real_Vector,
-           Inner_Product => "*",
-           Sqrt          => Sqrt);
+          (X_Scalar      => Real'Base,
+           Result_Real   => Real'Base,
+           X_Vector      => Real_Vector,
+           "abs"         => "+");
+      --  While the L2_Norm by definition uses the absolute values of the
+      --  elements of X_Vector, for real values the subsequent squaring
+      --  makes this unnecessary, so we substitute the "+" identity function
+      --  instead.
 
       function "abs" is new
         Vector_Elementwise_Operation
Index: s-gearop.adb
===================================================================
--- s-gearop.adb        (revision 179907)
+++ s-gearop.adb        (working copy)
@@ -336,9 +336,14 @@
    -- L2_Norm --
    -------------
 
-   function L2_Norm (X : Vector) return Scalar is
+   function L2_Norm (X : X_Vector) return Result_Real'Base is
+      Sum    : Result_Real'Base := 0.0;
    begin
-      return Sqrt (Inner_Product (X, X));
+      for J in X'Range loop
+         Sum := Sum + Result_Real'Base (abs X (J))**2;
+      end loop;
+
+      return Sqrt (Sum);
    end L2_Norm;
 
    ----------------------------------
Index: s-gearop.ads
===================================================================
--- s-gearop.ads        (revision 179894)
+++ s-gearop.ads        (working copy)
@@ -291,11 +291,12 @@
    -------------
 
    generic
-      type Scalar is private;
-      type Vector is array (Integer range <>) of Scalar;
-      with function Inner_Product (Left, Right : Vector) return Scalar is <>;
-      with function Sqrt (X : Scalar) return Scalar is <>;
-   function L2_Norm (X : Vector) return Scalar;
+      type X_Scalar is private;
+      type Result_Real is digits <>;
+      type X_Vector is array (Integer range <>) of X_Scalar;
+      with function "abs" (Right : X_Scalar) return Result_Real is <>;
+      with function Sqrt (X : Result_Real'Base) return Result_Real'Base is <>;
+   function L2_Norm (X : X_Vector) return Result_Real'Base;
 
    -------------------
    -- Outer_Product --

Reply via email to