Basic vector arithmetic
Mathematica
In Mathematica, curly braces denote a list or vector. Simple computations, like addition of two vectors or multiplying a vector by a scalar, are easy. Operations like multiplication and division work component by component.
In[1]:= {1,2,3} + {7,1,0}
Out[1]= {8, 3, 3}
In[2]:= 2*%
Out[2]= {16, 6, 6}
In[3]:= {1,2,3} * {7,1,0}
Out[3]= {7, 2, 0}
Maxima
In Maxima, square brackets denote a list or vector. Simple computations, like addition of two vectors or multiplying a vector by a scalar, are easy. Operations like multiplication and division work component by component.
(%i1) [1,2,3] + [7,1,0];
(%o1) [8, 3, 3]
(%i2) 2*%;
(%o2) [16, 6, 6]
(%i3) [1,2,3] * [7,1,0];
(%o3) [7, 2, 0]
Axiom
- In Axiom, a vector is simply a list (given with square bracket notation) that has been given a Vector type via the
-
operator or coerced to a vector type by context. Simple computations, like addition of two vectors or multiplying a vector by a scalar, are easy.
(1) -> [1,2,3]::Vector Expression Float + [7,1,0]
(1) ->
(1) [8.0,3.0,3.0]
Type: Vector Expression Float
(2) -> 2*%
(2) ->
(2) [16.0,6.0,6.0]
Type: Vector Expression Float
Dot and cross products
Mathematica
Mathematica contains functions for computing dot products and cross products. They are Dot[] and Cross[], respectively. It can also use the "." operator for dot products.
In[3]:= {1,2,3} . {7,1,0}
Out[3]= 9
In[4]:= Dot[ {1,2,3}, {7,1,0} ]
Out[4]= 9
In[5]:= Cross[ {1,1,0}, {0,1,1} ]
Out[5]= {1, -1, 1}
Maxima
A special operator "." calculates dot products.
(%i4) [1,2,3] . [7,1,0];
(%o4) 9
Unfortunately, Maxima contains no useful cross product operator. Luckily it is an easy matter to define a function that returns the cross product of two vectors.
(%i5) cross(a,b) := [ a[2]*b[3]-a[3]*b[2], a[3]*b[1]-a[1]*b[3], a[1]*b[2]-a[2]*b[1] ];
(%o5) cross(a, b) := [a b - a b , a b - a b , a b - a b ]
2 3 3 2 3 1 1 3 1 2 2 1
(%i6) cross( [1,1,0], [0,1,1] );
(%o6) [1, - 1, 1]
Axiom
Axiom contains functions for computing dot products and cross products. They are dot() and cross(), respectively.
(1) -> dot( [1,2,3], [7,1,0] )
(1) ->
(1) 9
Type: PositiveInteger
(2) -> cross( [1,1,0], [0,1,1] )
(2) ->
(2) [1,- 1,1]
Type: Vector Integer
Other functions
Mathematica
It is often convenient to know the length, or magnitude, of a vector. In Mathematica, the Norm[] function provides this.
In[7]:= Norm[ {1,-1,1} ]
Out[7]= Sqrt[3]
Maxima
It is often convenient to know the length, or magnitude, of a vector. In Maxima, there are a few functions you might consider using for this. One is norm(), but it doesn’t return what we expect. The abs() function applies componentwise, returning a vector whose entries have all been made positive; not what we want. The easiest way to get the magnitude of a vector is to write a small function for that.
(%i7) mag(a) := sqrt( a . a );
(%o7) mag(a) := SQRT(a . a)
(%i8) mag( [1, -1, 1] );
(%o8) SQRT(3)
Axiom
It is often convenient to know the length, or magnitude, of a vector. Axiom uses the length() function for this.
(1) -> length([1,-1,1] :: Vector Float )
(1) ->
(1) 1.7320508075 688772935
Type: Float
An alternative method is to imitate the mag functions, above, using the dot() operator that exists in Axiom already. One advantage of this is that dot() coerces its argument into Vector type, so it doesn’t have to be done explicitly.
(1) ->
(1) -> mag(a) == sqrt(dot(a,a))
Type: Void
(2) -> mag([1,-1,1])
Compiling function mag with type List Integer -> AlgebraicNumber
+-+
(2) \|3
Type: AlgebraicNumber
One feature that is missing from Axiom that both Maxima and Mathematica have is the ability to take the derivative of a vector or list (and have the derivative apply to each component). It is easy to add such a function, for example, the following DV().
(1) -> macro DV(vec,var) == map( f +-> D(f,var), vec )
Type: Void
(2) -> a := [ t^2, t^3 ]
(2) ->
2 3
(2) [t ,t ]
Type: List Polynomial Integer
(3) -> DV(a,t)
(3) ->
2
(3) [2t,3t ]
Type: List Polynomial Integer
Curl and Div
Mathematica
To use Curl[] and Div[] in Mathematica, the Calculus`VectorAnalysis` package must be loaded first.
In[1]:= <<Calculus`VectorAnalysis`
Curl[] and Div[] both accept a vector-valued function as the first argument, and the coordinate system as the second argument.
In[2]:= Div[ {x^2,x*y,x*y*z}, Cartesian[x,y,z] ]
Out[2]= 3 x + x y
In[3]:= Curl[ {x^2,x*y,x*y*z}, Cartesian[x,y,z] ]
Out[3]= {x z, -(y z), y}
Maxima
To use curl and div in Maxima, define these two functions.
(%i1) div(a) := diff(a[1],'x) + diff(a[2],'y) + diff(a[3],'z);
(%o1) div(a) := DIFF(a , 'x) + DIFF(a , 'y) + DIFF(a , 'z)
1 2 3
(%i2) curl(a) := [
diff(a[3],'y)-diff(a[2],'z),
diff(a[1],'z)-diff(a[3],'x),
diff(a[2],'x)-diff(a[1],'y) ];
(%o2) curl(a) := [DIFF(a , 'y) - DIFF(a , 'z), DIFF(a , 'z) - DIFF(a , 'x),
3 2 1 3
DIFF(a , 'x) - DIFF(a , 'y)]
2 1
Then, calculating a divergence or curl is simply a matter of passing a vector of functions based on the usual coordinate variables (x,y,z).
(%i3) div( [x^2,x*y,x*y*z] );
(%o3) x y + 3 x
(%i4) curl( [x^2,x*y,x*y*z] );
(%o4) [x z, - y z, y]
Axiom
To use curl and div in Axiom, define these two functions.
(1) -> div(a) == D(a(1),x) + D(a(2),y) + D(a(3),z)
Type: Void
(2) -> curl(a) == vector [ D(a(3),y)-D(a(2),z) , D(a(1),z)-D(a(3),x) , D(a(2),x)-D(a(1),y) ]
Type: Void
Then, calculating a divergence or curl is simply a matter of passing a vector of functions based on the usual coordinate variables (x,y,z).
(3) -> div( [x^2,x*y,x*y*z] )
Compiling function div with type List Polynomial Integer ->
Polynomial Integer
(3) x y + 3x
Type: Polynomial Integer
(4) -> curl( [x^2,x*y,x*y*z] )
(4) [x z,- y z,y]
Type: Vector Polynomial Integer
Computing the Jacobian
Mathematica
Computing a Jacobian in Mathematica is not built in, but it can
be done. The key to the process is the Outer[]
function.
In[1]:= x = r*Cos[t]
Out[1]= r Cos[t]
In[2]:= y = r*Sin[t]
Out[2]= r Sin[t]
In[3]:= jmat = Outer[ D, {x,y}, {r,t} ]
Out[3]= {{Cos[t], -(r Sin[t])}, {Sin[t], r Cos[t]}}
The Outer[]
function has created what we want, applying the Mathematica’s
D[]
function to our two lists.
For calculus work, it is usually the determinant that we need, and we can compute that as well.
In[4]:= Det[ jmat ]
2 2
Out[4]= r Cos[t] + r Sin[t]
In[5]:= Simplify[ % ]
Out[5]= r
For future convenience, we could define new functions to do this process automatically.
In[1]:= Jac[f_List?VectorQ, x_List] := Outer[D, f, x] /; Equal@@(Dimensions/@{f,x})
In[2]:= JDet[f_List?VectorQ, x_List] := Det[Jac[f, x]] /; Equal @@ (Dimensions /@ {f, x})
And we can check that these work:
In[3]:= x = r*Cos[t]; y = r*Sin[t];
In[4]:= Jac[ {x,y}, {r,t} ]
Out[4]= {{Cos[t], -(r Sin[t])}, {Sin[t], r Cos[t]}}
In[5]:= JDet[ {x,y}, {r,t} ]
2 2
Out[5]= r Cos[t] + r Sin[t]
Maxima
Computing a Jacobian in Maxima is not particularly straightforward, but it can
be done. The keys to the process are the outermap()
and apply()
functions.
(%i1) x : r*cos(t); y : r*sin(t);
(%o1) r cos(t)
(%o2) r sin(t)
(%i3) jlist : outermap( diff, [x,y], [r,t] );
(%o3) [[cos(t), - r sin(t)], [sin(t), r cos(t)]]
The outermap()
function has created what we want, applying the Maxima’s diff()
function to our two lists. Unfortunately, it doesn’t return a matrix, but rather a "list of lists." We can readily convert it to a matrix however by applying the matrix()
function to the lists of lists.
(%i4) jmat : apply( matrix, jlist );
[ cos(t) - r sin(t) ]
(%o4) [ ]
[ sin(t) r cos(t) ]
For calculus work, it is usually the determinant that we need, and we can compute that as well.
(%i5) determinant( jmat );
2 2
(%o5) r sin (t) + r cos (t)
(%i6) trigsimp(%);
(%o6) r
For future convenience, we could define new functions to do this process automatically.
(%i1) jac(a,b) := apply( 'matrix, outermap( 'diff, a,b ));
(%o1) jac(a, b) := apply('matrix, outermap('diff, a, b))
(%i2) jdet(a,b) := determinant( apply( 'matrix, outermap( 'diff, a,b )));
(%o2) jdet(a, b) := determinant(apply('matrix, outermap('diff, a, b)))
And we can check that these work:
(%i3) x : r*cos(t); y:r*sin(t);
(%o3) r cos(t)
(%o4) r sin(t)
(%i5) jac( [x,y], [r,t] );
[ cos(t) - r sin(t) ]
(%o5) [ ]
[ sin(t) r cos(t) ]
(%i6) jdet( [x,y], [r,t] );
2 2
(%o6) r sin (t) + r cos (t)
Saved macros
Maxima
The functions on this page can be stored once and automatically loaded in later Maxima sessions. To do so, we need only make a macro file.
Note: these commands happen outside Maxima. First we create a subdirectory of our home to put our macros in, called .maxima
. Then we create a file in it called maxima-init.mac
and put the function definitions in it.
$ mkdir ~/.maxima
$ cat > ~/.maxima/maxima-init.mac
cross(a,b) := [ a[2]*b[3]-a[3]*b[2], a[3]*b[1]-a[1]*b[3], a[1]*b[2]-a[2]*b[1] ];
mag(a) := sqrt( a . a );
div(a) := [ diff(a[1],'x), diff(a[2],'y), diff(a[3],'z) ];
curl(a) := [
diff(a[3],'y)-diff(a[2],'z),
diff(a[1],'z)-diff(a[3],'x),
diff(a[2],'x)-diff(a[1],'y) ];
Press Ctrl-D after the last line, to end the file.
At the beginning of new maxima sessions, the macros will automatically be loaded.