A vector is defined as having three dimensions as being represented by an ordered collection of three numbers:   (X, Y, Z).

If you imagine a graph with the   x   and   y   axis being at right angles to each other and having a third,   z   axis coming out of the page, then a triplet of numbers,   (X, Y, Z)   would represent a point in the region,   and a vector from the origin to the point.

Given the vectors:

        A = (a1,  a2,  a3) 
        B = (b1,  b2,  b3) 
        C = (c1,  c2,  c3) 

then the following common vector products are defined:

 The dot product       (a scalar quantity)
  A • B = a1b1   +   a2b2   +   a3b3  
 The cross product       (a vector quantity)
  A x B = (a2b3  -   a3b2,     a3b1   -   a1b3,     a1b2   -   a2b1)  
 The scalar triple product       (a scalar quantity)
  A • (B x C) 
 The vector triple product       (a vector quantity)
  A x (B x C) 


Task

Given the three vectors:

        a = ( 3,    4,    5)
        b = ( 4,    3,    5)
        c = (-5,  -12,  -13)

 Create a named function/subroutine/method to compute the dot product of two vectors.
 Create a function to compute the cross product of two vectors.
 Optionally create a function to compute the scalar triple product of three vectors.
 Optionally create a function to compute the vector triple product of three vectors.
 Compute and display: a • b
 Compute and display: a x b
 Compute and display: a • (b x c), the scalar triple product.
 Compute and display: a x (b x c), the vector triple product.


References

   A starting page on Wolfram MathWorld is   Vector Multiplication .
   Wikipedia   dot product. 
   Wikipedia   cross product. 
   Wikipedia   triple product.


Related tasks

   Dot product
   Quaternion type


:- module vector_product.
:- interface.
 
:- import_module io.
:- pred main(io::di, io::uo) is det.
 
:- implementation.
:- import_module int, list, string.
 
main(!IO) :-
    A = vector3d(3, 4, 5),
    B = vector3d(4, 3, 5),
    C = vector3d(-5, -12, -13),
    io.format("A . B = %d\n", [i(A `dot_product` B)], !IO),
    io.format("A x B = %s\n", [s(to_string(A `cross_product` B))], !IO),
    io.format("A . (B x C) = %d\n", [i(scalar_triple_product(A, B, C))], !IO),
    io.format("A x (B x C) = %s\n", [s(to_string(vector_triple_product(A, B, C)))], !IO).
 
:- type vector3d ---> vector3d(int, int, int).
 
:- func dot_product(vector3d, vector3d) = int.
 
dot_product(vector3d(A1, A2, A3), vector3d(B1, B2, B3)) =
    A1 * B1 + A2 * B2 + A3 * B3.
 
:- func cross_product(vector3d, vector3d) = vector3d.
 
cross_product(vector3d(A1, A2, A3), vector3d(B1, B2, B3)) =
    vector3d(A2 * B3 - A3 * B2, A3 * B1 - A1 * B3, A1 * B2 - A2 * B1).
 
:- func scalar_triple_product(vector3d, vector3d, vector3d) = int.
 
scalar_triple_product(A, B, C) = A `dot_product` (B `cross_product` C).
 
:- func vector_triple_product(vector3d, vector3d, vector3d) = vector3d.
 
vector_triple_product(A, B, C) = A `cross_product` (B `cross_product` C).
 
:- func to_string(vector3d) = string.
 
to_string(vector3d(X, Y, Z)) =
    string.format("(%d, %d, %d)", [i(X), i(Y), i(Z)]).