arithmetic/src/linearalgebra/vector/VectorFast.mg


GENERIC MODULE VectorFast(R, V);
Arithmetic for Modula-3, see doc for details
 VR is needed to reveal the structure of V.T 

<* UNUSED *>
CONST
  Module = "VectorFast.";

<* INLINE *>
PROCEDURE AssertEqualSize (READONLY x, y: T; ) =
  BEGIN
    <* ASSERT NUMBER(x) = NUMBER(y), "Vectors must have the same size." *>
  END AssertEqualSize;

PROCEDURE IsZero (READONLY x: T; ): BOOLEAN =
  BEGIN
    FOR i := FIRST(x) TO LAST(x) DO
      IF x[i] # R.Zero THEN RETURN FALSE; END
    END;
    RETURN TRUE;
  END IsZero;

PROCEDURE Equal (READONLY x, y: T; ): BOOLEAN =
  BEGIN
    AssertEqualSize(x, y);
    FOR i := FIRST(x) TO LAST(x) DO
      IF x[i] # y[i] THEN RETURN FALSE; END
    END;
    RETURN TRUE;
  END Equal;

PROCEDURE Add (READONLY x, y: T; ): V.T =
  VAR z := NEW(V.T, NUMBER(x));
  BEGIN
    AssertEqualSize(x, y);
    FOR i := FIRST(x) TO LAST(x) DO z[i] := x[i] + y[i]; END;
    RETURN z;
  END Add;

PROCEDURE Sub (READONLY x, y: T; ): V.T =
  VAR z := NEW(V.T, NUMBER(x));
  BEGIN
    AssertEqualSize(x, y);
    FOR i := FIRST(x) TO LAST(x) DO z[i] := x[i] - y[i]; END;
    RETURN z;
  END Sub;

PROCEDURE Neg (READONLY x: T; ): V.T =
  VAR z := NEW(V.T, NUMBER(x));
  BEGIN
    FOR i := FIRST(x) TO LAST(x) DO z[i] := -x[i]; END;
    RETURN z;
  END Neg;

PROCEDURE Scale (READONLY x: T; y: R.T; ): V.T =
  VAR z := NEW(V.T, NUMBER(x));
  BEGIN
    FOR i := FIRST(x) TO LAST(x) DO z[i] := x[i] * y; END;
    RETURN z;
  END Scale;

PROCEDURE Inner (READONLY x, y: T; ): R.T =
  VAR sum := R.Zero;
  BEGIN
    AssertEqualSize(x, y);
    FOR i := FIRST(x) TO LAST(x) DO sum := sum + x[i] * y[i]; END;
    RETURN sum;
  END Inner;

PROCEDURE Sum (READONLY x: T; ): R.T =
  VAR sum := R.Zero;
  BEGIN
    FOR i := FIRST(x) TO LAST(x) DO sum := sum + x[i]; END;
    RETURN sum;
  END Sum;

PROCEDURE Max (READONLY x: T; ): R.T =
  VAR max := R.NegInf;
  BEGIN
    FOR i := FIRST(x) TO LAST(x) DO max := MAX(max, x[i]); END;
    RETURN max;
  END Max;

PROCEDURE Min (READONLY x: T; ): R.T =
  VAR min := R.PosInf;
  BEGIN
    FOR i := FIRST(x) TO LAST(x) DO min := MIN(min, x[i]); END;
    RETURN min;
  END Min;

PROCEDURE ArithSeq (num: CARDINAL; from: R.T; by: R.T; ): V.T =
  VAR x := NEW(V.T, num);
  BEGIN
    IF num > 0 THEN
      x[0] := from;
      FOR j := 1 TO num - 1 DO from := from + by; x[j] := from; END;
    END;
    RETURN x;
  END ArithSeq;

PROCEDURE GeomSeq (num: CARDINAL; from: R.T; by: R.T; ): V.T =
  VAR x := NEW(V.T, num);
  BEGIN
    IF num > 0 THEN
      x[0] := from;
      FOR j := 1 TO num - 1 DO from := from * by; x[j] := from; END;
    END;
    RETURN x;
  END GeomSeq;

BEGIN
END VectorFast.