## `linalg::scalarProduct` -- scalar product of vectors

#### Introduction

`linalg::scalarProduct``(u, v)` computes the scalar product of the vectors u = [u1,...,un] and v = [v1,...,vn] with respect to the standard basis, namely the sum sum(u[i]*conjugate(v[i]),i=1..n).

#### Call(s)

`linalg::scalarProduct(u, v)`

#### Parameters

`u, v` | - | vectors of the same dimension (a vector is an n x 1 or 1 x n matrix of a domain of category `Cat::Matrix`)

#### Returns

an element of the component ring of `u` and `v`.

#### Side Effects

Properties of identifiers are taken into account.

#### Related Functions

`linalg::angle`, `linalg::crossProduct`, `linalg::isUnitary`, `linalg::factorQR`, `linalg::orthog`, `norm`

#### Details

- The scalar product is also called ``inner product'' or ``dot product''.
- If the component ring of the vectors `u` and `v` does not define the entry `"conjugate"`, then `linalg::scalarProduct` uses the scalar product defined by sum(u[i]*v[i],i=1..n).
- The vectors `u` and `v` must be defined over the same component ring.
- `linalg::scalarProduct` can be redefined to a different scalar product. This also affects the behaviour of functions such as `linalg::angle`, `linalg::factorQR`, `linalg::isUnitary`, `norm` (for vectors and matrices), `linalg::orthog` and `linalg::pseudoInverse` depend on the definition of `linalg::scalarProduct`. See example 3.

#### Example 1

We compute the scalar product of the vectors [I,1] and [1,-I]:

    >> MatC := Dom::Matrix(Dom::Complex):
       u := MatC([I, 1]): v := MatC([1, -I]):
       linalg::scalarProduct(u, v)

                                        2 I

#### Example 2

We compute the scalar product of the vectors u=[u1,u2] and v=[v1,v2] with the symbolic entries u1, u2, v1, v2 over the standard component ring for matrices:

    >> delete u1, u2, v1, v2:
       u := matrix([u1, u2]): v := matrix([v1, v2]):
       linalg::scalarProduct(u, v)

                        u1 conjugate(v1) + u2 conjugate(v2)

You can use `assume` to tell the system that the symbolic components are to represent real numbers:

    >> assume([u1, u2, v1, v2], Type::Real):

Then the scalar product of u and v simplifies to:

    >> linalg::scalarProduct(u, v)

                                   u1 v1 + u2 v2

#### Example 3

One particular scalar product in the real vector space of continuous functions on the interval [0,1] is defined by

    (f,g) = int( f(t)*g(t),t=0..1 ).

To compute an orthogonal basis corresponding to the polynomial basis 1, t, t^2, t^3, ... with respect to this scalar product, we replace the standard scalar product by the following procedure:

    >> standardScalarProduct := linalg::scalarProduct:
       unprotect(linalg):
       linalg::scalarProduct := proc(u, v)
           local F, f, t;
       begin
           // (0)
           f := expr(u[1] * v[1]);

           // (1)
           t := indets(f);
           if t = {} then t := genident("t") else t := op(t, 1) end_if;

           // (2)
           F := int(f, t = 0..1);

           // (3)
           u::dom::coeffRing::coerce(F)
       end:

We start with step `(0)` to convert f(t)*g(t) to an expression of a basic domain type, such that the system function `int` in step `(2)` can handle its input (this is not necessary if the elements of the component ring of the vectors are already represented by elements of basic domains).

Step `(1)` extracts the indeterminate of the polynomials, step `(2)` computes the scalar product as defined above and step `(3)` converts the result back to an element of the component ring of vectors `u` and `v`.

Note that we need to unprotect the write protected identifier `linalg`, otherwise the assignment would lead to an error message.

We next create the matrix which consists of the first five of the above polynomials:

    >> P := matrix([[1, t, t^2, t^3, t^4]])

                               +-       2   3   4-+
                               | 1, t, t , t , t  |
                               +-                -+

If we now perform the Gram-Schmidt orthogonalization procedure on the columns of `P` with the function `linalg::orthog`, we get:

    >> S := linalg::orthog(linalg::col(P, 1..4))

          --
          |
          |  +- -+  +-       -+  +-       2      -+
          |  | 1 |, | t - 1/2 |, | - t + t  + 1/6 |,
          |  +- -+  +-       -+  +-              -+
          --

             +-                        -+ --
             |           2              |  |
             |  3 t   3 t     3         |  |
             |  --- - ---- + t  - 1/20  |  |
             |   5     2                |  |
             +-                        -+ --

Each vector in `S` is orthogonal to the other vectors in `S` with respect to the modified scalar product. We check this for the first vector:

    >> linalg::scalarProduct(S[1], S[j]) $ j = 2..nops(S)

                                      0, 0, 0

Finally, we undo the redefinition of the scalar product, so as not to run into trouble with subsequent computations:

    >> linalg::scalarProduct := standardScalarProduct:
       protect(linalg, Error):

Do you have questions or comments?
Copyright © SciFace Software GmbH & Co. KG 2000