Vector products

From Rosetta Code
Vector products is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

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 scaler 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. Create a function to compute the scalar triple product of three vectors.
  4. 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 using the scaler triple product function.
  8. Compute and display: a x b x c using the vector triple product function.
References
C.f.

D

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

struct V3 {

   immutable union {
       struct { real x, y, z ; }
       real[3] v ;
   }
   static V3 fromArray(real[] vec) {
       int cut = min(3,vec.length) ;
       real[] r = vec[0..cut] ~ [0.0L, 0, 0][cut..3] ;
       return V3(r[0], r[1], r[2]) ;
   }
   real dot(V3 rhs) {
       return x*rhs.x + y*rhs.y + z*rhs.z ;
   }
   V3 cross(V3 rhs) {
       return V3(y*rhs.z - z*rhs.y,
                 z*rhs.x - x*rhs.z,
                 x*rhs.y - y*rhs.x) ;
   }
   string toString() { return to!string(v) ; }

}

V3 vectorTriple(V3 a, V3 b, V3 c) {

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

}

real scalarTriple(V3 a, V3 b, V3 c) {

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

}

void main() {

   V3 a = {3,4,5}, b = V3(4,3,5), c = V3.fromArray([-5,-12,-13]) ;
   writefln("a = %s, b = %s, c = %s", a, b, 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]

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>

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

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>

Python

<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.

Library: matrix

<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]