Vector products

From Rosetta Code
Revision as of 16:45, 6 September 2011 by 79.50.194.180 (talk) (Updated D code)
Task
Vector products
You are encouraged to solve this task according to the task description, using any language you may know.

Define a vector 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 vectors A = (a1, a2, a3); B = (b1, b2, b3); and C = (c1, c2, c3); then the following common vector products are defined:

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

Given the three vectors: a = (3, 4, 5); b = (4, 3, 5); c = (-5, -12, -13):

  1. Create a named function/subroutine/method to compute the dot product of two vectors.
  2. Create a function to compute the cross product of two vectors.
  3. Optionally create a function to compute the scalar triple product of three vectors.
  4. Optionally create a function to compute the vector triple product of three vectors.
  5. Compute and display: a • b
  6. Compute and display: a x b
  7. Compute and display: a • b x c, the scaler triple product.
  8. Compute and display: a x b x c, the vector triple product.
References
C.f.

Ada

not using Ada.Numerics.Real_Arrays, to show some features of the language.

Ada determines which function to call not only on the types of the parameters, but also on the return type. That way we can use the same name for all multiplications (scalar and cross). But, if we add another one to stretch the vector, we get an ambiguity error, since the compiler can't know if A*(B*C) with result-type Vector is meant to be A stretched by the scalar product of B and C, or the cross product of A and the result of the cross product of B and C. Here, I used type qualification to tell the compiler that the result of (B*C) is of type Vector.

vector.adb: <lang Ada>with Ada.Text_IO;

procedure Vector is

  type Float_Vector is array (Positive range <>) of Float;
  package Float_IO is new Ada.Text_IO.Float_IO (Float);
  procedure Vector_Put (X : Float_Vector) is
  begin
     Ada.Text_IO.Put ("(");
     for I in X'Range loop
        Float_IO.Put (X (I), Aft => 1, Exp => 0);
        if I /= X'Last then
           Ada.Text_IO.Put (", ");
        end if;
     end loop;
     Ada.Text_IO.Put (")");
  end Vector_Put;
  -- cross product
  function "*" (Left, Right : Float_Vector) return Float_Vector is
  begin
     if Left'Length /= Right'Length then
        raise Constraint_Error with "vectors of different size in dot product";
     end if;
     if Left'Length /= 3 then
        raise Constraint_Error with "dot product only implemented for R**3";
     end if;
     return Float_Vector'(Left (Left'First + 1) * Right (Right'First + 2) -
                            Left (Left'First + 2) * Right (Right'First + 1),
                          Left (Left'First + 2) * Right (Right'First) -
                            Left (Left'First) * Right (Right'First + 2),
                          Left (Left'First) * Right (Right'First + 1) -
                            Left (Left'First + 1) * Right (Right'First));
  end "*";
  -- scalar product
  function "*" (Left, Right : Float_Vector) return Float is
     Result : Float := 0.0;
     I, J : Positive;
  begin
     if Left'Length /= Right'Length then
        raise Constraint_Error with "vectors of different size in scalar product";
     end if;
     I := Left'First; J := Right'First;
     while I <= Left'Last and then J <= Right'Last loop
        Result := Result + Left (I) * Right (J);
        I := I + 1; J := J + 1;
     end loop;
     return Result;
  end "*";
  -- stretching
  function "*" (Left : Float_Vector; Right : Float) return Float_Vector is
     Result : Float_Vector (Left'Range);
  begin
     for I in Left'Range loop
        Result (I) := Left (I) * Right;
     end loop;
     return Result;
  end "*";
  A : constant Float_Vector := (3.0, 4.0, 5.0);
  B : constant Float_Vector := (4.0, 3.0, 5.0);
  C : constant Float_Vector := (-5.0, -12.0, -13.0);

begin

  Ada.Text_IO.Put ("A: "); Vector_Put (A); Ada.Text_IO.New_Line;
  Ada.Text_IO.Put ("B: "); Vector_Put (B); Ada.Text_IO.New_Line;
  Ada.Text_IO.Put ("C: "); Vector_Put (C); Ada.Text_IO.New_Line;
  Ada.Text_IO.New_Line;
  Ada.Text_IO.Put ("A dot B = "); Float_IO.Put (A * B, Aft => 1, Exp => 0);
  Ada.Text_IO.New_Line;
  Ada.Text_IO.Put ("A x B = "); Vector_Put (A * B);
  Ada.Text_IO.New_Line;
  Ada.Text_IO.Put ("A dot (B x C) = "); Float_IO.Put (A * (B * C), Aft => 1, Exp => 0);
  Ada.Text_IO.New_Line;
  Ada.Text_IO.Put ("A x (B x C) = "); Vector_Put (A * Float_Vector'(B * C));
  Ada.Text_IO.New_Line;

end Vector;</lang>

Output:

A: ( 3.0,  4.0,  5.0)
B: ( 4.0,  3.0,  5.0)
C: (-5.0, -12.0, -13.0)

A dot B = 49.0
A x B = ( 5.0,  5.0, -7.0)
A dot (B x C) =  6.0
A x (B x C) = (-267.0, 204.0, -3.0)

ALGOL 68

Translation of: Python

Note: This specimen retains the original Python coding style.

Works with: ALGOL 68 version Revision 1 - no extensions to language used.
Works with: ALGOL 68G version Any - tested with release 1.18.0-9h.tiny.

<lang algol68>MODE FIELD = INT; FORMAT field fmt = $g(-0)$;

MODE VEC = [3]FIELD; FORMAT vec fmt = $"("f(field fmt)", "f(field fmt)", "f(field fmt)")"$;

PROC crossp = (VEC a, b)VEC:(

   #Cross product of two 3D vectors#
   CO ASSERT(LWB a = LWB b AND UPB a = UPB b AND UPB b = 3 # "For 3D vectors only" #); CO
   (a[2]*b[3] - a[3]*b[2], a[3]*b[1] - a[1]*b[3], a[1]*b[2] - a[2]*b[1])

);

PRIO MAXLWB = 8, MINUPB=8;

OP MAXLWB = (VEC a, b)INT: (LWB a<LWB b|LWB a|LWB b); OP MINUPB = (VEC a, b)INT: (UPB a>UPB b|UPB a|UPB b);

PROC dotp = (VEC a, b)FIELD:(

   #Dot product of two vectors#
   FIELD sum := 0;
   FOR i FROM a MAXLWB b TO a MINUPB b DO sum +:= a[i]*b[i] OD;
   sum

);

PROC scalartriplep = (VEC a, b, c)VEC:(

   #Scalar triple product of three vectors: "a . (b x c)"#
   dotp(a, crossp(b, c))

);

PROC vectortriplep = (VEC a, b, c)VEC:(

   #Vector triple product of three vectors: "a x (b x c)"#
   crossp(a, crossp(b, c))

);

  1. Declare some useful operators #

PRIO DOT = 5, X = 5; OP (VEC, VEC)FIELD DOT = dotp; OP (VEC, VEC)VEC X = crossp;

main:(

   VEC a=(3, 4, 5), b=(4, 3, 5), c=(-5, -12, -13);
   printf(($"a = "f(vec fmt)";  b = "f(vec fmt)";  c = "f(vec fmt)l$ , a, b, c));
   printf($"Using PROCedures:"l$);
   printf(($"a . b = "f(field fmt)l$, dotp(a,b)));
   printf(($"a x b = "f(vec fmt)l$, crossp(a,b)));
   printf(($"a . (b x c) = "f(field fmt)l$, scalartriplep(a, b, c)));
   printf(($"a x (b x c) = "f(vec fmt)l$, vectortriplep(a, b, c)));
   printf($"Using OPerators:"l$);
   printf(($"a . b = "f(field fmt)l$, a DOT b));
   printf(($"a x b = "f(vec fmt)l$, a X b));
   printf(($"a . (b x c) = "f(field fmt)l$, a DOT (b X c)));
   printf(($"a x (b x c) = "f(vec fmt)l$, a X (b X c)))

)</lang> Output:

a = (3, 4, 5);  b = (4, 3, 5);  c = (-5, -12, -13)
Using PROCedures:
a . b = 49
a x b = (5, 5, -7)
a . (b x c) = 6
a x (b x c) = (-267, 204, -3)
Using OPerators:
a . b = 49
a x b = (5, 5, -7)
a . (b x c) = 6
a x (b x c) = (-267, 204, -3)

C#

<lang csharp>using System; using System.Windows.Media.Media3D;

class VectorProducts {

   static double ScalarTripleProduct(Vector3D a, Vector3D b, Vector3D c)
   {
       return Vector3D.DotProduct(a, Vector3D.CrossProduct(b, c));
   }
   static Vector3D VectorTripleProduct(Vector3D a, Vector3D b, Vector3D c)
   {
       return Vector3D.CrossProduct(a, Vector3D.CrossProduct(b, c));
   }
   static void Main()
   {
       var a = new Vector3D(3, 4, 5);
       var b = new Vector3D(4, 3, 5);
       var c = new Vector3D(-5, -12, -13);
       Console.WriteLine(Vector3D.DotProduct(a, b));
       Console.WriteLine(Vector3D.CrossProduct(a, b));
       Console.WriteLine(ScalarTripleProduct(a, b, c));
       Console.WriteLine(VectorTripleProduct(a, b, c));
   }

}</lang> Output: <lang>49 5;5;-7 6 -267;204;-3</lang>

C++

<lang cpp>#include <iostream>

template< class T > class D3Vector {

template< class U > friend std::ostream & operator<<( std::ostream & , const D3Vector & ) ;

public :

  D3Vector( T a , T b , T c ) {
     x = a ;
     y = b ;
     z = c ;
  }
  T dotproduct ( const D3Vector & rhs ) {
     T scalar = x * rhs.x + y * rhs.y + z * rhs.z ;
     return scalar ;
  }
  D3Vector crossproduct ( const D3Vector & rhs ) {
     T a = y * rhs.z - z * rhs.y ;
     T b = z * rhs.x - x * rhs.z ;
     T c = x * rhs.y - y * rhs.x ;
     D3Vector product( a , b , c ) ;
     return product ;
  }
  D3Vector triplevec( D3Vector & a , D3Vector & b ) {
     return crossproduct ( a.crossproduct( b ) ) ;
  }
  T triplescal( D3Vector & a, D3Vector & b ) {
     return dotproduct( a.crossproduct( b ) ) ;
  }

private :

  T x , y , z ;  

} ;

template< class T > std::ostream & operator<< ( std::ostream & os , const D3Vector<T> & vec ) {

  os << "( "  << vec.x << " ,  " << vec.y << " ,  " << vec.z << " )" ;
  return os ;

}

int main( ) {

  D3Vector<int> a( 3 , 4 , 5 ) , b ( 4 , 3 , 5 ) , c( -5 , -12 , -13 ) ;
  std::cout << "a . b : " << a.dotproduct( b ) << "\n" ;
  std::cout << "a x b : " << a.crossproduct( b ) << "\n" ;
  std::cout << "a . b x c : " << a.triplescal( b , c ) << "\n" ;
  std::cout << "a x b x c : " << a.triplevec( b , c ) << "\n" ;
  return 0 ;

}</lang>

Output:

a . b : 49
a x b : ( 5 , 5 , -7 )
a . b x c : 6
a x b x c : ( -267 , 204 , -3 )

Clojure

<lang clojure>(defrecord Vector [x y z])

(defn dot

 [U V]
 (+ (* (:x U) (:x V))
    (* (:y U) (:y V))
    (* (:z U) (:z V))))

(defn cross

 [U V]
 (new Vector
      (- (* (:y U) (:z V)) (* (:z U) (:y V)))
      (- (* (:z U) (:x V)) (* (:x U) (:z V)))
      (- (* (:x U) (:y V)) (* (:y U) (:x V)))))

(let [a (new Vector 3 4 5)

     b (new Vector 4 3 5)
     c (new Vector -5 -12 -13)]
 (doseq
   [prod (list
           (dot a b)
           (cross a b)
           (dot a (cross b c))
           (cross a (cross b c)))]
   (println prod)))</lang>

Output:

49
#:user.Vector{:x 5, :y 5, :z -7}
6
#:user.Vector{:x -267, :y 204, :z -3}

D

<lang d>import std.stdio, std.algorithm, std.conv, std.numeric;

struct V3 {

   union {
       struct { double x, y, z; }
       double[3] v;
   }
   pure nothrow double dot(in V3 rhs) const {
       return dotProduct(v, rhs.v);
   }
   pure nothrow V3 cross(in V3 rhs) const {
       return V3(y*rhs.z - z*rhs.y,
                 z*rhs.x - x*rhs.z,
                 x*rhs.y - y*rhs.x);
   }
   string toString() const { return text(v); }

}

pure nothrow double scalarTriple(in V3 a, in V3 b, in V3 c) {

   return a.dot(b.cross(c));

}

pure nothrow V3 vectorTriple(in V3 a, in V3 b, in V3 c) {

   return a.cross(b.cross(c));

}

void main() {

   const V3 a = {3, 4, 5},
            b = {4, 3, 5},
            c = {-5, -12, -13};
   writeln("a = ", a);
   writeln("b = ", b);
   writeln("c = ", c);
   writeln("a . b = ", a.dot(b));
   writeln("a x b = ", a.cross(b));
   writeln("a . (b x c) = ", scalarTriple(a,b,c));
   writeln("a x (b x c) = ", vectorTriple(a,b,c));

}</lang> Output:

a = [3, 4, 5]
b = [4, 3, 5]
c = [-5, -12, -13]
a . b = 49
a x b = [5, 5, -7]
a . (b x c) = 6
a x (b x c) = [-267, 204, -3]

Euphoria

<lang euphoria>constant X = 1, Y = 2, Z = 3

function dot_product(sequence a, sequence b)

   return a[X]*b[X] + a[Y]*b[Y] + a[Z]*b[Z]

end function

function cross_product(sequence a, sequence b)

   return { a[Y]*b[Z] - a[Z]*b[Y],
            a[Z]*b[X] - a[X]*b[Z],
            a[X]*b[Y] - a[Y]*b[X] }

end function

function scalar_triple(sequence a, sequence b, sequence c)

   return dot_product( a, cross_product( b, c ) )

end function

function vector_triple( sequence a, sequence b, sequence c)

   return cross_product( a, cross_product( b, c ) )

end function

constant a = { 3, 4, 5 }, b = { 4, 3, 5 }, c = { -5, -12, -13 }

puts(1,"a = ") ? a puts(1,"b = ") ? b puts(1,"c = ") ? c puts(1,"a dot b = ") ? dot_product( a, b ) puts(1,"a x b = ") ? cross_product( a, b ) puts(1,"a dot (b x c) = ") ? scalar_triple( a, b, c ) puts(1,"a x (b x c) = ") ? vector_triple( a, b, c )</lang>

Output:

a = {3,4,5}
b = {4,3,5}
c = {-5,-12,-13}
a dot b = 49
a x b = {5,5,-7}
a dot (b x c) = 6
a x (b x c) = {-267,204,-3}

Fortran

Works with: Fortran version 95 and later

Specialized for 3-dimensional vectors.

<lang fortran>program VectorProducts

 real, dimension(3)  :: a, b, c
 a = (/ 3, 4, 5 /)
 b = (/ 4, 3, 5 /)
 c = (/ -5, -12, -13 /)
 print *, dot_product(a, b)
 print *, cross_product(a, b)
 print *, s3_product(a, b, c)
 print *, v3_product(a, b, c)

contains

 function cross_product(a, b)
   real, dimension(3) :: cross_product
   real, dimension(3), intent(in) :: a, b
   cross_product(1) = a(2)*b(3) - a(3)*b(2)
   cross_product(2) = a(3)*b(1) - a(1)*b(3)
   cross_product(3) = a(1)*b(2) - b(1)*a(2)
 end function cross_product
 function s3_product(a, b, c)
   real :: s3_product
   real, dimension(3), intent(in) :: a, b, c
   s3_product = dot_product(a, cross_product(b, c))
 end function s3_product
 function v3_product(a, b, c)
   real, dimension(3) :: v3_product
   real, dimension(3), intent(in) :: a, b, c
   v3_product = cross_product(a, cross_product(b, c))
 end function v3_product

end program VectorProducts</lang> Output

     49.0000
     5.00000         5.00000        -7.00000
     6.00000
    -267.000         204.000        -3.00000

GAP

<lang gap>DotProduct := function(u, v) return u*v; end;

CrossProduct := function(u, v) return [ u[2]*v[3] - u[3]*v[2], u[3]*v[1] - u[1]*v[3], u[1]*v[2] - u[2]*v[1] ]; end;

ScalarTripleProduct := function(u, v, w) return DotProduct(u, CrossProduct(v, w)); end;

VectorTripleProduct := function(u, v, w) return CrossProduct(u, CrossProduct(v, w)); end;

a := [3, 4, 5]; b := [4, 3, 5]; c := [-5, -12, -13];

DotProduct(a, b);

  1. 49

CrossProduct(a, b);

  1. [ 5, 5, -7 ]

ScalarTripleProduct(a, b, c);

  1. 6
  1. Another way to get it

Determinant([a, b, c]);

  1. 6

VectorTripleProduct(a, b, c);

  1. [ -267, 204, -3 ]</lang>

Go

<lang go>package main

import "fmt"

type vector struct {

   x, y, z float64

}

var (

   a = vector{3, 4, 5}
   b = vector{4, 3, 5}
   c = vector{-5, -12, -13}

)

func dot(a, b vector) float64 {

   return a.x*b.x + a.y*b.y + a.z*b.z

}

func cross(a, b vector) vector {

   return vector{a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x}

}

func s3(a, b, c vector) float64 {

   return dot(a, cross(b, c))

}

func v3(a, b, c vector) vector {

   return cross(a, cross(b, c))

}

func main() {

   fmt.Println(dot(a, b))
   fmt.Println(cross(a, b))
   fmt.Println(s3(a, b, c))
   fmt.Println(v3(a, b, c))

}</lang> Output:

49
{5 5 -7}
6
{-267 204 -3}

Haskell

<lang haskell>type Vector a = [a] type Scalar a = a

a,b,c,d :: Vector Int a = [ 3, 4, 5 ] b = [ 4, 3, 5 ] c = [-5,-12,-13 ] d = [ 3, 4, 5, 6 ]

dot :: (Num t) => Vector t -> Vector t -> Scalar t dot u v | length u == length v = sum $ zipWith (*) u v

       | otherwise = error "Dotted Vectors must be of equal dimension."

cross :: (Num t) => Vector t -> Vector t -> Vector t cross u v | length u == 3 && length v == 3 =

            [u !! 1 * v !! 2 - u !! 2 * v !! 1,
             u !! 2 * v !! 0 - u !! 0 * v !! 2,
             u !! 0 * v !! 1 - u !! 1 * v !! 0]
         | otherwise = error "Crossed Vectors must both be three dimensional."

scalarTriple :: (Num t) => Vector t -> Vector t -> Vector t -> Scalar t scalarTriple q r s = dot q $ cross r s

vectorTriple :: (Num t) => Vector t -> Vector t -> Vector t -> Vector t vectorTriple q r s = cross q $ cross r s

main = do

  mapM_ putStrLn [ "a . b     = " ++ (show $ dot a b)
                 , "a x b     = " ++ (show $ cross a b)
                 , "a . b x c = " ++ (show $ scalarTriple a b c)
                 , "a x b x c = " ++ (show $ vectorTriple a b c) 
                 , "a . d     = " ++ (show $ dot a d) ]</lang>

Output:

a . b     = 49
a x b     = [5,5,-7]
a . b x c = 6
a x b x c = [-267,204,-3]
a . d     = *** Exception: Dotted Vectors must be of equal dimension.

Icon and Unicon

<lang icon># record type to store a 3D vector record Vector3D(x, y, z)

  1. procedure to display vector as a string

procedure toString (vector)

 return "(" || vector.x || ", " || vector.y || ", " || vector.z || ")"

end

procedure dotProduct (a, b)

 return a.x * b.x + a.y * b.y + a.z * b.z

end

procedure crossProduct (a, b)

 x := a.y * b.z - a.z * b.y
 y := a.z * b.x - a.x * b.z
 z := a.x * b.y - a.y * b.x
 return Vector3D(x, y, z)

end

procedure scalarTriple (a, b, c)

 return dotProduct (a, crossProduct (b, c))

end

procedure vectorTriple (a, b, c)

 return crossProduct (a, crossProduct (b, c))

end

  1. main procedure, to run given test

procedure main ()

 a := Vector3D(3, 4, 5)
 b := Vector3D(4, 3, 5)
 c := Vector3D(-5, -12, -13)
 writes ("A.B : " || toString(a) || "." || toString(b) || " = ")
 write (dotProduct (a, b))
 writes ("AxB : " || toString(a) || "x" || toString(b) || " = ")
 write (toString(crossProduct (a, b)))
 writes ("A.(BxC) : " || toString(a) || ".(" || toString(b) || "x" || toString(c) || ") = ")
 write (scalarTriple (a, b, c))
 writes ("Ax(BxC) : " || toString(a) || "x(" || toString(b) || "x" || toString(c) || ") = ")
 write (toString(vectorTriple (a, b, c)))

end </lang>

Output:

A.B : (3, 4, 5).(4, 3, 5) = 49
AxB : (3, 4, 5)x(4, 3, 5) = (5, 5, -7)
A.(BxC) : (3, 4, 5).((4, 3, 5)x(-5, -12, -13)) = 6
Ax(BxC) : (3, 4, 5)x((4, 3, 5)x(-5, -12, -13)) = (-267, 204, -3)

J

Based on j:Essays/Complete Tensor: <lang j>CT=: C.!.2 @ (#:i.) @ $~ ip=: +/ .* NB. inner product cross=: ] ip CT@#@[ ip [</lang>

An alternative definition for cross (based on finding the determinant of a 3 by 3 matrix where one row is unit vectors) could be:

<lang j>cross=: [: > [: -&.>/ .(*&.>) (<"1=i.3) , ,:&:(<"0)</lang>

Implementation:<lang j>a=: 3 4 5 b=: 4 3 5 c=: -5 12 13

A=: 0 {:: ] NB. contents of the first box on the right B=: 1 {:: ] NB. contents of the second box on the right C=: 2 {:: ] NB. contents of the third box on the right

dotP=: A ip B crossP=: A cross B scTriP=: A ip B cross C veTriP=: A cross B cross C</lang>

Required example:

<lang j> dotP a;b 49

  crossP a;b

5 5 _7

  scTriP a;b;c

6

  veTriP a;b;c

_267 204 _3</lang>

Java

Works with: Java version 1.5+

All operations which return vectors give vectors containing Doubles. <lang java5>public class VectorProds{

   public static class Vector3D<T extends Number>{
       private T a, b, c;
       public Vector3D(T a, T b, T c){
           this.a = a;
           this.b = b;
           this.c = c;
       }
       public double dot(Vector3D<?> vec){
           return (a.doubleValue() * vec.a.doubleValue() +
                   b.doubleValue() * vec.b.doubleValue() +
                   c.doubleValue() * vec.c.doubleValue());
       }
       public Vector3D<Double> cross(Vector3D<?> vec){
           Double newA = b.doubleValue()*vec.c.doubleValue() - c.doubleValue()*vec.b.doubleValue();
           Double newB = c.doubleValue()*vec.a.doubleValue() - a.doubleValue()*vec.c.doubleValue();
           Double newC = a.doubleValue()*vec.b.doubleValue() - b.doubleValue()*vec.a.doubleValue();
           return new Vector3D<Double>(newA, newB, newC);
       }
       public double scalTrip(Vector3D<?> vecB, Vector3D<?> vecC){
           return this.dot(vecB.cross(vecC));
       }
       public Vector3D<Double> vecTrip(Vector3D<?> vecB, Vector3D<?> vecC){
           return this.cross(vecB.cross(vecC));
       }
       @Override
       public String toString(){
           return "<" + a.toString() + ", " + b.toString() + ", " + c.toString() + ">";
       }
   }
   public static void main(String[] args){
       Vector3D<Integer> a = new Vector3D<Integer>(3, 4, 5);
       Vector3D<Integer> b = new Vector3D<Integer>(4, 3, 5);
       Vector3D<Integer> c = new Vector3D<Integer>(-5, -12, -13);
       System.out.println(a.dot(b));
       System.out.println(a.cross(b));
       System.out.println(a.scalTrip(b, c));
       System.out.println(a.vecTrip(b, c));
   }

}</lang> Output:

49.0
<5.0, 5.0, -7.0>
6.0
<-267.0, 204.0, -3.0>

Liberty BASIC

<lang lb> print "Vector products of 3-D vectors"

   print "Dot   product of 3,4,5 and 4,3,5 is "
   print DotProduct(   "3,4,5", "4,3,5")
   print "Cross product of 3,4,5 and 4,3,5 is "
   print CrossProduct$( "3,4,5", "4,3,5")
   print "Scalar triple product of 3,4,5,    4,3,5    -5, -12, -13 is "
   print ScalarTripleProduct( "3,4,5", "4,3,5", "-5, -12, -13")
   print "Vector triple product of 3,4,5,    4,3,5    -5, -12, -13 is "
   print VectorTripleProduct$( "3,4,5", "4,3,5", "-5, -12, -13")


   end
   function DotProduct( i$, j$)
       ix =val( word$( i$, 1, ","))
       iy =val( word$( i$, 2, ","))
       iz =val( word$( i$, 3, ","))
       jx =val( word$( j$, 1, ","))
       jy =val( word$( j$, 2, ","))
       jz =val( word$( j$, 3, ","))
       DotProduct = ix *jx +iy *jy + iz *jz
   end function
   function CrossProduct$( i$, j$)
       ix =val( word$( i$, 1, ","))
       iy =val( word$( i$, 2, ","))
       iz =val( word$( i$, 3, ","))
       jx =val( word$( j$, 1, ","))
       jy =val( word$( j$, 2, ","))
       jz =val( word$( j$, 3, ","))
       cpx =iy *jz -iz *jy
       cpy =iz *jx -ix *jz
       cpz =ix *jy -iy *jx
       CrossProduct$ =str$( cpx); ","; str$( cpy); ","; str$( cpz)
   end function
   function ScalarTripleProduct( i$, j$, k$))
       ScalarTripleProduct =DotProduct( i$, CrossProduct$( j$, k$))
   end function
   function VectorTripleProduct$( i$, j$, k$))
       VectorTripleProduct$ =CrossProduct$( i$, CrossProduct$( j$, k$))
   end function
END SUB
</lang>

Lua

<lang lua>Vector = {} function Vector.new( _x, _y, _z )

   return { x=_x, y=_y, z=_z }

end

function Vector.dot( A, B )

   return A.x*B.x + A.y*B.y + A.z*B.z

end

function Vector.cross( A, B )

   return { x = A.y*B.z - A.z*B.y,
            y = A.z*B.x - A.x*B.z,
            z = A.x*B.y - A.y*B.x }

end

function Vector.scalar_triple( A, B, C )

   return Vector.dot( A, Vector.cross( B, C ) )

end

function Vector.vector_triple( A, B, C )

   return Vector.cross( A, Vector.cross( B, C ) )

end


A = Vector.new( 3, 4, 5 ) B = Vector.new( 4, 3, 5 ) C = Vector.new( -5, -12, -13 )

print( Vector.dot( A, B ) )

r = Vector.cross(A, B ) print( r.x, r.y, r.z )

print( Vector.scalar_triple( A, B, C ) )

r = Vector.vector_triple( A, B, C ) print( r.x, r.y, r.z )</lang>

49
5	5	-7
6
-267	204	-3


Mathematica

<lang Mathematica> a={3,4,5}; b={4,3,5}; c={-5,-12,-13}; a.b Cross[a,b] a.Cross[b,c] Cross[a,Cross[b,c]] </lang> Output

49
{5,5,-7}
6
{-267,204,-3}

Nemerle

<lang Nemerle>using System.Console;

module VectorProducts3d {

   Dot(x : int * int * int, y : int * int * int) : int
   {
       def (x1, x2, x3) = x;
       def (y1, y2, y3) = y;
       (x1 * y1) + (x2 * y2) + (x3 * y3)
   }
   
   Cross(x : int * int * int, y : int * int * int) : int * int * int
   {
       def (x1, x2, x3) = x;
       def (y1, y2, y3) = y;
       ((x2 * y3 - x3 * y2), (x3 * y1 - x1 * y3), (x1 * y2 - x2 * y1))
   }
   
   ScalarTriple(a : int * int * int, b : int * int * int, c : int * int * int) : int
   {
       Dot(a, Cross(b, c))
   }
   
   VectorTriple(a : int * int * int, b : int * int * int, c : int * int * int) : int * int * int
   {
       Cross(a, Cross(b, c))
   }
   
   Main() : void
   {
       def a = (3, 4, 5); def b = (4, 3, 5); def c = (-5, -12, -13);
       WriteLine(Dot(a, b)); WriteLine(Cross(a, b));
       WriteLine(ScalarTriple(a, b, c));
       WriteLine(VectorTriple(a, b, c));
   }

}</lang> Outputs

49
(5, 5, -7)
6
(-267, 204, -3)

OCaml

<lang ocaml>let a = (3.0, 4.0, 5.0) let b = (4.0, 3.0, 5.0) let c = (-5.0, -12.0, -13.0)

let string_of_vector (x,y,z) =

 Printf.sprintf "(%g, %g, %g)" x y z

let dot (a1, a2, a3) (b1, b2, b3) =

 (a1 *. b1) +. (a2 *. b2) +. (a3 *. b3)

let cross (a1, a2, a3) (b1, b2, b3) =

 (a2 *. b3 -. a3 *. b2,
  a3 *. b1 -. a1 *. b3,
  a1 *. b2 -. a2 *. b1)

let scalar_triple a b c =

 dot a (cross b c)

let vector_triple a b c =

 cross a (cross b c)

let () =

 Printf.printf "a: %s\n" (string_of_vector a);
 Printf.printf "b: %s\n" (string_of_vector b);
 Printf.printf "c: %s\n" (string_of_vector c);
 Printf.printf "a . b = %g\n" (dot a b);
 Printf.printf "a x b = %s\n" (string_of_vector (cross a b));
 Printf.printf "a . (b x c) = %g\n" (scalar_triple a b c);
 Printf.printf "a x (b x c) = %s\n" (string_of_vector (vector_triple a b c));
</lang>

outputs:

a: (3, 4, 5)
b: (4, 3, 5)
c: (-5, -12, -13)
a . b = 49
a x b = (5, 5, -7)
a . (b x c) = 6
a x (b x c) = (-267, 204, -3)


Octave

Octave handles naturally vectors / matrices.

<lang octave>a = [3, 4, 5]; b = [4, 3, 5]; c = [-5, -12, -13];

function r = s3prod(a, b, c)

 r = dot(a, cross(b, c));

endfunction

function r = v3prod(a, b, c)

 r = cross(a, cross(b, c));

endfunction

% 49 dot(a, b) % or matrix-multiplication between row and column vectors a * b'

% 5 5 -7 cross(a, b) % only for 3d-vectors

% 6 s3prod(a, b, c)

% -267 204 -3 v3prod(a, b, c)</lang>

PARI/GP

<lang parigp>dot(u,v)={

 sum(i=1,#u,u[i]*v[i])

}; cross(u,v)={

 [u[2]*v[3] - u[3]*v[2], u[3]*v[1] - u[1]*v[3], u[1]*v[2] - u[2]*v[1]]

}; striple(a,b,c)={

 dot(a,cross(b,c))

}; vtriple(a,b,c)={

 cross(a,cross(b,c))

};

a = [3,4,5]; b = [4,3,5]; c = [-5,-12,-13]; dot(a,b) cross(a,b) striple(a,b,c) vtriple(a,b,c)</lang> Output:

49
[5, 5, -7]
6
[-267, 204, -3]

Perl

<lang Perl>package Vector; use List::Util 'sum'; use List::MoreUtils 'pairwise';

sub new { shift; bless [@_] }

use overload (

       '""'    => sub { "(@{+shift})" },
       '&'     => sub { sum pairwise { $a * $b } @{+shift}, @{+shift} },
       '^'     => sub {
                               my @a = @{+shift};
                               my @b = @{+shift};
                               bless [ $a[1]*$b[2] - $a[2]*$b[1],
                                       $a[2]*$b[0] - $a[0]*$b[2],
                                       $a[0]*$b[1] - $a[1]*$b[0] ]
                       },

);

package main; my $a = Vector->new(3, 4, 5); my $b = Vector->new(4, 3, 5); my $c = Vector->new(-5, -12, -13);

print "a = $a b = $b c = $c\n"; print "$a . $b = ", $a & $b, "\n"; print "$a x $b = ", $a ^ $b, "\n"; print "$a . ($b x $c) = ", $a & ($b ^ $c), "\n"; print "$a x ($b x $c) = ", $a ^ ($b ^ $c), "\n";</lang>

Output:

a = (3 4 5) b = (4 3 5) c = (-5 -12 -13)
(3 4 5) . (4 3 5) = 49
(3 4 5) x (4 3 5) = (5 5 -7)
(3 4 5) . ((4 3 5) x (-5 -12 -13)) = 6
(3 4 5) x ((4 3 5) x (-5 -12 -13)) = (-267 204 -3)

Perl 6

<lang perl6>sub infix:<⋅> { [+] @^a »*« @^b }

sub infix:<⨯>([$a1, $a2, $a3], [$b1, $b2, $b3]) {

   [ $a2*$b3 - $a3*$b2,
     $a3*$b1 - $a1*$b3,
     $a1*$b2 - $a2*$b1 ];

}

sub scalar-triple-product { @^a ⋅ (@^b ⨯ @^c) } sub vector-triple-product { @^a ⨯ (@^b ⨯ @^c) }

my @a = <3 4 5>; my @b = <4 3 5>; my @c = <-5 -12 -13>;

say (:@a, :@b, :@c).perl; say "a ⋅ b = { @a ⋅ @b }"; say "a ⨯ b = <{ @a ⨯ @b }>"; say "a ⋅ (b ⨯ c) = { scalar-triple-product(@a, @b, @c) }"; say "a ⨯ (b ⨯ c) = <{ vector-triple-product(@a, @b, @c) }>";</lang> Output:

("a" => ["3", "4", "5"], "b" => ["4", "3", "5"], "c" => ["-5", "-12", "-13"])
a ⋅ b = 49
a ⨯ b = <5 5 -7>
a ⋅ (b ⨯ c) = 6
a ⨯ (b ⨯ c) = <-267 204 -3>

PicoLisp

<lang PicoLisp>(de dotProduct (A B)

  (sum * A B) )

(de crossProduct (A B)

  (list
     (- (* (cadr A) (caddr B)) (* (caddr A) (cadr B)))
     (- (* (caddr A) (car B)) (* (car A) (caddr B)))
     (- (* (car A) (cadr B)) (* (cadr A) (car B))) ) )

(de scalarTriple (A B C)

  (dotProduct A (crossProduct B C)) )

(de vectorTriple (A B C)

  (crossProduct A (crossProduct B C)) )</lang>

Test:

(setq
   A ( 3   4   5)
   B ( 4   3   5)
   C (-5 -12 -13) )

: (dotProduct A B)
-> 49

: (crossProduct A B)
-> (5 5 -7)

: (scalarTriple A B C)
-> 6

: (vectorTriple A B C)
-> (-267 204 -3)

PL/I

<lang PL/I> /* dot product, cross product, etc. 4 June 2011 */

test_products: procedure options (main);

  declare a(3) fixed initial (3, 4, 5);
  declare b(3) fixed initial (4, 3, 5);
  declare c(3) fixed initial (-5, -12, -13);
  declare e(3) fixed;
  put skip list ('a . b =', dot_product(a, b));
  call cross_product(a, b, e);  put skip list ('a x b =', e);
  put skip list ('a . (b x c) =',  scalar_triple_product(a, b, c));
  call vector_triple_product(a, b, c, e); put skip list ('a x (b x c) =', e);


dot_product: procedure (a, b) returns (fixed);

  declare (a, b) (*) fixed;
  return (sum(a*b));

end dot_product;

cross_product: procedure (a, b, c);

  declare (a, b, c) (*) fixed;
  c(1) = a(2)*b(3) - a(3)*b(2);
  c(2) = a(3)*b(1) - a(1)*b(3);
  c(3) = a(1)*b(2) - a(2)*b(1);

end cross_product;

scalar_triple_product: procedure (a, b, c) returns (fixed);

  declare (a, b, c)(*) fixed;
  declare t(hbound(a, 1)) fixed;
  call cross_product(b, c, t);
  return (dot_product(a, t));

end scalar_triple_product;

vector_triple_product: procedure (a, b, c, e);

  declare (a, b, c, e)(*) fixed;
  declare t(hbound(a,1))  fixed;
  call cross_product(b, c, t);
  call cross_product(a, t, e);

end vector_triple_product;

end test_products; </lang> Results:

a . b =                       49
a x b =                        5                       5                      -7
a . (b x c) =                  6
a x (b x c) =               -267                     204                      -3

<lang> /* This version uses the ability of PL/I to return arrays. */


/* dot product, cross product, etc. 6 June 2011 */

test_products: procedure options (main);

  define structure 1 vector, 2 vec(3) fixed;
  declare (a, b, c) type(vector);
  a.vec(1) =  3; a.vec(2) =   4; a.vec(3) =   5;
  b.vec(1) =  4; b.vec(2) =   3; b.vec(3) =   5;
  c.vec(1) = -5; c.vec(2) = -12; c.vec(3) = -13;
  put skip list ('a . b =',       dot_product  (a, b) );
  put skip list ('a x b =',       cross_product(a, b).vec);
  put skip list ('a . (b x c) =', scalar_triple_product(a, b, c) );
  put skip list ('a x (b x c) =', vector_triple_product(a, b, c).vec);


dot_product: procedure (a, b) returns (fixed);

  declare (a, b) type(vector);
  return (sum(a.vec*b.vec));

end dot_product;

cross_product: procedure (a, b) returns (type(vector));

  declare (a, b) type(vector);
  declare c type vector;
  c.vec(1) = a.vec(2)*b.vec(3) - a.vec(3)*b.vec(2);
  c.vec(2) = a.vec(3)*b.vec(1) - a.vec(1)*b.vec(3);
  c.vec(3) = a.vec(1)*b.vec(2) - a.vec(2)*b.vec(1);
  return (c);

end cross_product;

scalar_triple_product: procedure (a, b, c) returns (fixed);

  declare (a, b, c) type(vector);
  declare t type (vector);
  t =  cross_product(b, c);
  return (dot_product(a, t));

end scalar_triple_product;

vector_triple_product: procedure (a, b, c) returns (type(vector));

  declare (a, b, c) type(vector);
  declare (t, e) type (vector);
  t = cross_product(b, c);
  e = cross_product(a, t);
  return (e);

end vector_triple_product;

end test_products; </lang>

The output is:
a . b =                       49 
a x b =                        5                       5                      -7 
a . (b x c) =                  6 
a x (b x c) =               -267                     204                      -3 

PureBasic

<lang PureBasic>Structure vector

 x.f 
 y.f
 z.f

EndStructure

convert vector to a string for display

Procedure.s toString(*v.vector)

 ProcedureReturn "[" + StrF(*v\x, 2) + ", " + StrF(*v\y, 2) + ", " + StrF(*v\z, 2) + "]"

EndProcedure

Procedure.f dotProduct(*a.vector, *b.vector)

 ProcedureReturn *a\x * *b\x + *a\y * *b\y + *a\z * *b\z

EndProcedure

Procedure crossProduct(*a.vector, *b.vector, *r.vector)

 *r\x = *a\y * *b\z - *a\z * *b\y
 *r\y = *a\z * *b\x - *a\x * *b\z
 *r\z = *a\x * *b\y - *a\y * *b\x

EndProcedure

Procedure.f scalarTriple(*a.vector, *b.vector, *c.vector)

 Protected r.vector
 crossProduct(*b, *c, r)
 ProcedureReturn dotProduct(*a, r)

EndProcedure

Procedure vectorTriple(*a.vector, *b.vector, *c.vector, *r.vector)

 Protected r.vector
 crossProduct(*b, *c, r)
 crossProduct(*a, r, *r)

EndProcedure

If OpenConsole()

 Define.vector a, b, c, r
 a\x = 3: a\y = 4: a\z = 5
 b\x = 4: b\y = 3: b\z = 5
 c\x = -5: c\y = -12: c\z = -13
 
 PrintN("a = " + toString(a) + ", b = " + toString(b) + ", c = " + toString(c))
 PrintN("a . b = " + StrF(dotProduct(a, b), 2))
 crossProduct(a, b, r)
 PrintN("a x b = " + toString(r))
 PrintN("a . b x c  = " + StrF(scalarTriple(a, b, c), 2))
 vectorTriple(a, b, c, r)
 PrintN("a x b x c = " + toString(r))
 
 Print(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input()
 CloseConsole()

EndIf</lang> Sample output:

a = [3.00, 4.00, 5.00], b = [4.00, 3.00, 5.00], c = [-5.00, -12.00, -13.00]
a . b = 49.00
a x b = [5.00, 5.00, -7.00]
a . b x c  = 6.00
a x b x c = [-267.00, 204.00, -3.00]

Python

The solution is in the form of an Executable library. <lang python>def crossp(a, b):

   Cross product of two 3D vectors
   assert len(a) == len(b) == 3, 'For 3D vectors only'
   a1, a2, a3 = a
   b1, b2, b3 = b
   return (a2*b3 - a3*b2, a3*b1 - a1*b3, a1*b2 - a2*b1)

def dotp(a,b):

   Dot product of two eqi-dimensioned vectors
   assert len(a) == len(b), 'Vector sizes must match'
   return sum(aterm * bterm for aterm,bterm in zip(a, b))

def scalartriplep(a, b, c):

   Scalar triple product of three vectors: "a . (b x c)"
   return dotp(a, crossp(b, c))

def vectortriplep(a, b, c):

   Vector triple product of three vectors: "a x (b x c)"
   return crossp(a, crossp(b, c))

if __name__ == '__main__':

   a, b, c = (3, 4, 5), (4, 3, 5), (-5, -12, -13)
   print("a = %r;  b = %r;  c = %r" % (a, b, c))
   print("a . b =", dotp(a,b))
   print("a x b =", crossp(a,b))
   print("a . (b x c) =", scalartriplep(a, b, c))
   print("a x (b x c) =", vectortriplep(a, b, c))</lang>
Sample output
a = (3, 4, 5);  b = (4, 3, 5);  c = (-5, -12, -13)
a . b = 49
a x b = (5, 5, -7)
a . (b x c) = 6
a x (b x c) = (-267, 204, -3)
Note

The popular numpy package has functions for dot and cross products.

Ruby

Dot product is also known as inner product. The standard library already defines Vector#inner_product, so this program only defines the other three methods.

<lang ruby>require 'matrix'

class Vector

 def cross_product(v)
   unless size == 3 && v.size == 3
     raise ArgumentError, "Vectors must have size 3"
   end
   Vector[self[1] * v[2] - self[2] * v[1],
          self[2] * v[0] - self[0] * v[2],
          self[0] * v[1] - self[1] * v[0]]
 end
 def scalar_triple_product(b, c)
   self.inner_product(b.cross_product c)
 end
 def vector_triple_product(b, c)
   self.cross_product(b.cross_product c)
 end

end

a = Vector[3, 4, 5] b = Vector[4, 3, 5] c = Vector[-5, -12, -13]

puts "a dot b = #{a.inner_product b}" puts "a cross b = #{a.cross_product b}" puts "a dot (b cross c) = #{a.scalar_triple_product b, c}" puts "a cross (b cross c) = #{a.vector_triple_product b, c}"</lang>

Output:

a dot b = 49
a cross b = Vector[5, 5, -7]
a dot (b cross c) = 6
a cross (b cross c) = Vector[-267, 204, -3]

Scheme

Works with: Guile
Works with: Gauche

Using modified dot-product function from the Dot product task. <lang scheme>(define (dot-product A B)

   (apply + (map * (vector->list A) (vector->list B))))

(define (cross-product A B) (define len (vector-length A)) (define xp (make-vector (vector-length A) #f)) (let loop ((n 0)) (vector-set! xp n (- (* (vector-ref A (modulo (+ n 1) len)) (vector-ref B (modulo (+ n 2) len))) (* (vector-ref A (modulo (+ n 2) len)) (vector-ref B (modulo (+ n 1) len))))) (if (eqv? len (+ n 1)) xp (loop (+ n 1)))))

(define (scalar-triple-product A B C) (dot-product A (cross-product B C)))

(define (vector-triple-product A B C) (cross-product A (cross-product B C)))


(define A #( 3 4 5)) (define B #(4 3 5)) (define C #(-5 -12 -13))

(display "A = ")(display A)(newline) (display "B = ")(display B)(newline) (display "C = ")(display C)(newline) (newline) (display "A . B = ")(display (dot-product A B))(newline) (display "A x B = ")(display (cross-product A B))(newline) (display "A . B x C = ")(display (scalar-triple-product A B C))(newline) (display "A x B x C = ") (display (vector-triple-product A B C))(newline)</lang>

Output:

A = #(3 4 5)
B = #(4 3 5)
C = #(-5 -12 -13)

A . B = 49
A x B = #(5 5 -7)
A . B x C = 6
A x B x C = #(-267 204 -3)

Seed7

The program below uses Seed7s capaibility to define operator symbols. The operators dot and X are defined with with priority 6 and assiciativity left-to-right.

<lang seed7>$ include "seed7_05.s7i";

 include "float.s7i";

const type: vec3 is new struct

   var float: x is 0.0;
   var float: y is 0.0;
   var float: z is 0.0;
 end struct;

const func vec3: vec3 (in float: x, in float: y, in float: z) is func

 result
   var vec3: result is vec3.value;
 begin
   result.x := x;
   result.y := y;
   result.z := z;
 end func;

$ syntax expr: .(). dot .() is -> 6; const func float: (in vec3: a) dot (in vec3: b) is

 return a.x*b.x + a.y*b.y + a.z*b.z;

$ syntax expr: .(). X .() is -> 6; const func vec3: (in vec3: a) X (in vec3: b) is

 return vec3(a.y*b.z - a.z*b.y,
             a.z*b.x - a.x*b.z,
             a.x*b.y - a.y*b.x);

const func string: str (in vec3: v) is

 return "(" <& v.x <& ", " <& v.y <& ", " <& v.z <& ")";

enable_output(vec3);

const func float: scalarTriple (in vec3: a, in vec3: b, in vec3: c) is

 return a dot (b X c);

const func vec3: vectorTriple (in vec3: a, in vec3: b, in vec3: c) is

 return a X (b X c);

const proc: main is func

 local
   const vec3: a is vec3(3.0, 4.0, 5.0);
   const vec3: b is vec3(4.0, 3.0, 5.0);
   const vec3: c is vec3(-5.0, -12.0, -13.0);
 begin
   writeln("a = " <& a <& ", b = " <& b <& ", c = " <& c);
   writeln("a . b      = " <& a dot b);
   writeln("a x b      = " <& a X b);
   writeln("a .(b x c) = " <& scalarTriple(a, b, c));
   writeln("a x(b x c) = " <& vectorTriple(a, b, c));
 end func;</lang>

Tcl

<lang tcl>proc dot {A B} {

   lassign $A a1 a2 a3
   lassign $B b1 b2 b3
   expr {$a1*$b1 + $a2*$b2 + $a3*$b3}

} proc cross {A B} {

   lassign $A a1 a2 a3
   lassign $B b1 b2 b3
   list [expr {$a2*$b3 - $a3*$b2}] \

[expr {$a3*$b1 - $a1*$b3}] \ [expr {$a1*$b2 - $a2*$b1}] } proc scalarTriple {A B C} {

   dot $A [cross $B $C]

} proc vectorTriple {A B C} {

   cross $A [cross $B $C]

}</lang> Demonstrating: <lang tcl>set a {3 4 5} set b {4 3 5} set c {-5 -12 -13} puts "a • b = [dot $a $b]" puts "a x b = [cross $a $b]" puts "a • b x c = [scalarTriple $a $b $c]" puts "a x b x c = [vectorTriple $a $b $c]"</lang>

Output:

a • b = 49
a x b = 5 5 -7
a • b x c = 6
a x b x c = -267 204 -3

Visual Basic .NET

Class: Vector3D <lang vbnet>Public Class Vector3D

   Private _x, _y, _z As Double
   Public Sub New(ByVal X As Double, ByVal Y As Double, ByVal Z As Double)
       _x = X
       _y = Y
       _z = Z
   End Sub
   Public Property X() As Double
       Get
           Return _x
       End Get
       Set(ByVal value As Double)
           _x = value
       End Set
   End Property
   Public Property Y() As Double
       Get
           Return _y
       End Get
       Set(ByVal value As Double)
           _y = value
       End Set
   End Property
   Public Property Z() As Double
       Get
           Return _z
       End Get
       Set(ByVal value As Double)
           _z = value
       End Set
   End Property
   Public Function Dot(ByVal v2 As Vector3D) As Double
       Return (X * v2.X) + (Y * v2.Y) + (Z * v2.Z)
   End Function
   Public Function Cross(ByVal v2 As Vector3D) As Vector3D
       Return New Vector3D((Y * v2.Z) - (Z * v2.Y), _
                           (Z * v2.X) - (X * v2.Z), _
                           (X * v2.Y) - (Y * v2.X))
   End Function
   Public Function ScalarTriple(ByVal v2 As Vector3D, ByVal v3 As Vector3D) As Double
       Return Me.Dot(v2.Cross(v3))
   End Function
   Public Function VectorTriple(ByRef v2 As Vector3D, ByVal v3 As Vector3D) As Vector3D
       Return Me.Cross(v2.Cross(v3))
   End Function
   Public Overrides Function ToString() As String
       Return String.Format("({0}, {1}, {2})", _x, _y, _z)
   End Function

End Class</lang>

Module: Module1 <lang vbnet>Module Module1

   Sub Main()
       Dim v1 As New Vector3D(3, 4, 5)
       Dim v2 As New Vector3D(4, 3, 5)
       Dim v3 As New Vector3D(-5, -12, -13)
       Console.WriteLine("v1: {0}", v1.ToString())
       Console.WriteLine("v2: {0}", v2.ToString())
       Console.WriteLine("v3: {0}", v3.ToString())
       Console.WriteLine()
       Console.WriteLine("v1 . v2 = {0}", v1.Dot(v2))
       Console.WriteLine("v1 x v2 = {0}", v1.Cross(v2).ToString())
       Console.WriteLine("v1 . (v2 x v3) = {0}", v1.ScalarTriple(v2, v3))
       Console.WriteLine("v1 x (v2 x v3) = {0}", v1.VectorTriple(v2, v3))
   End Sub

End Module</lang>

Output:

v1: (3, 4, 5)
v2: (4, 3, 5)
v3: (-5, -12, -13)

v1 . v2 = 49
v1 x v2 = (5, 5, -7)
v1 . (v2 x v3) = 6
v1 x (v2 x v3) = (-267, 204, -3)