arithmetic/src/linearalgebra/vector/VectorBasic.mg

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

```<* UNUSED *>
CONST
Module = "VectorBasic.";

<* 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 NOT R.IsZero(x[i]) 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 NOT R.Equal(x[i], y[i]) THEN RETURN FALSE; END
END;
RETURN TRUE;
END Equal;

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

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] := R.Sub(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] := R.Neg(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] := R.Mul(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
END;
RETURN sum;
END Inner;

PROCEDURE Dot (READONLY x, y: T; ): R.T =
VAR sum := R.Zero;
BEGIN
AssertEqualSize(x, y);
FOR i := FIRST(x) TO LAST(x) DO
END;
RETURN sum;
END Dot;
```
* should be generalized to finding an orthonormal basis of the space orthogonal to a given set of vectors one way to do this: let the matrix have size (n,m) with less columns than rows (m<n) clip the matrix to size (m+1,m) and create a column vector orthogonal to it the j-th component is computed by the determinant of the limitted matrix with the j-th row removed now iterate to the matrix of size (m+2,m+1) and so on

for floating point numbers this can be done more efficiently by a QR factorization

PROCEDURE Cross (x, y: T; ): T = BEGIN RAISE Error(Err.not_implemented); END Cross; *

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

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 := R.Add(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 := R.Mul(from, by); x[j] := from; END;
END;
RETURN x;
END GeomSeq;

BEGIN
END VectorBasic.
```
```

```