This is maxima.info, produced by makeinfo version 5.1 from maxima.texi.


File: maxima.info,  Node: Matrices and Linear Algebra,  Next: Пакет affine,  Prev: Массивы,  Up: Top

23 Matrices and Linear Algebra
******************************

* Menu:

* Introduction to Matrices and Linear Algebra::  
* Functions and Variables for Matrices and Linear Algebra::  


File: maxima.info,  Node: Introduction to Matrices and Linear Algebra,  Next: Functions and Variables for Matrices and Linear Algebra,  Prev: Matrices and Linear Algebra,  Up: Matrices and Linear Algebra

23.1 Introduction to Matrices and Linear Algebra
================================================

* Menu:

* Dot::                         
* Matrices::                         
* Vectors::                     
* eigen::


File: maxima.info,  Node: Dot,  Next: Matrices,  Prev: Introduction to Matrices and Linear Algebra,  Up: Introduction to Matrices and Linear Algebra

23.1.1 Dot
----------

The operator ‘.’ represents noncommutative multiplication and scalar
product.  When the operands are 1-column or 1-row matrices ‘a’ and ‘b’,
the expression ‘a.b’ is equivalent to ‘sum (a[i]*b[i], i, 1,
length(a))’.  If ‘a’ and ‘b’ are not complex, this is the scalar
product, also called the inner product or dot product, of ‘a’ and ‘b’.
The scalar product is defined as ‘conjugate(a).b’ when ‘a’ and ‘b’ are
complex; ‘innerproduct’ in the ‘eigen’ package provides the complex
scalar product.

   When the operands are more general matrices, the product is the
matrix product ‘a’ and ‘b’.  The number of rows of ‘b’ must equal the
number of columns of ‘a’, and the result has number of rows equal to the
number of rows of ‘a’ and number of columns equal to the number of
columns of ‘b’.

   To distinguish ‘.’ as an arithmetic operator from the decimal point
in a floating point number, it may be necessary to leave spaces on
either side.  For example, ‘5.e3’ is ‘5000.0’ but ‘5 . e3’ is ‘5’ times
‘e3’.

   There are several flags which govern the simplification of
expressions involving ‘.’, namely ‘dot0nscsimp’, ‘dot0simp’, ‘dot1simp’,
‘dotassoc’, ‘dotconstrules’, ‘dotdistrib’, ‘dotexptsimp’, ‘dotident’,
and ‘dotscrules’.


File: maxima.info,  Node: Matrices,  Next: Vectors,  Prev: Dot,  Up: Introduction to Matrices and Linear Algebra

23.1.2 Matrices
---------------

Matrices are handled with speed and memory-efficiency in mind.  This
means that assigning a matrix to a variable will create a reference to,
not a copy of the matrix.  If the matrix is modified all references to
the matrix point to the modified object (See ‘copymatrix’ for a way of
avoiding this):
     (%i1) M1: matrix([0,0],[0,0]);
                                 [ 0  0 ]
     (%o1)                       [      ]
                                 [ 0  0 ]
     (%i2) M2: M1;
                                 [ 0  0 ]
     (%o2)                       [      ]
                                 [ 0  0 ]
     (%i3) M1[1][1]: 2;
     (%o3)                           2
     (%i4) M2;
                                 [ 2  0 ]
     (%o4)                       [      ]
                                 [ 0  0 ]

   Converting a matrix to nested lists and vice versa works the
following way:
     (%i1) l: [[1,2],[3,4]];
     (%o1)                   [[1, 2], [3, 4]]
     (%i2) M1: apply('matrix,l);
                                 [ 1  2 ]
     (%o2)                       [      ]
                                 [ 3  4 ]
     (%i3) M2: transpose(M1);
                                 [ 1  3 ]
     (%o3)                       [      ]
                                 [ 2  4 ]
     (%i4) args(M2);
     (%o4)                   [[1, 3], [2, 4]]


File: maxima.info,  Node: Vectors,  Next: eigen,  Prev: Matrices,  Up: Introduction to Matrices and Linear Algebra

23.1.3 Vectors
--------------

‘vect’ is a package of functions for vector analysis.  ‘load ("vect")’
loads this package, and ‘demo ("vect")’ displays a demonstration.

   The vector analysis package can combine and simplify symbolic
expressions including dot products and cross products, together with the
gradient, divergence, curl, and Laplacian operators.  The distribution
of these operators over sums or products is governed by several flags,
as are various other expansions, including expansion into components in
any specific orthogonal coordinate systems.  There are also functions
for deriving the scalar or vector potential of a field.

   The ‘vect’ package contains these functions: ‘vectorsimp’,
‘scalefactors’, ‘express’, ‘potential’, and ‘vectorpotential’.

   By default the ‘vect’ package does not declare the dot operator to be
a commutative operator.  To get a commutative dot operator ‘.’, the
command ‘declare(".", commutative)’ must be executed.


File: maxima.info,  Node: eigen,  Prev: Vectors,  Up: Introduction to Matrices and Linear Algebra

23.1.4 eigen
------------

The package ‘eigen’ contains several functions devoted to the symbolic
computation of eigenvalues and eigenvectors.  Maxima loads the package
automatically if one of the functions ‘eigenvalues’ or ‘eigenvectors’ is
invoked.  The package may be loaded explicitly as ‘load ("eigen")’.

   ‘demo ("eigen")’ displays a demonstration of the capabilities of this
package.  ‘batch ("eigen")’ executes the same demonstration, but without
the user prompt between successive computations.

   The functions in the ‘eigen’ package are:
‘innerproduct’, ‘unitvector’, ‘columnvector’, ‘gramschmidt’,
‘eigenvalues’,
‘eigenvectors’, ‘uniteigenvectors’, and ‘similaritytransform’.


File: maxima.info,  Node: Functions and Variables for Matrices and Linear Algebra,  Prev: Introduction to Matrices and Linear Algebra,  Up: Matrices and Linear Algebra

23.2 Functions and Variables for Matrices and Linear Algebra
============================================================

 -- Function: addcol (<M>, <list_1>, …, <list_n>)

     Appends the column(s) given by the one or more lists (or matrices)
     onto the matrix <M>.

     See also ‘addrow’ and ‘append’.

 -- Function: addrow (<M>, <list_1>, …, <list_n>)

     Appends the row(s) given by the one or more lists (or matrices)
     onto the matrix <M>.

     See also ‘addcol’ and ‘append’.

 -- Function: adjoint (<M>)

     Returns the adjoint of the matrix <M>.  The adjoint matrix is the
     transpose of the matrix of cofactors of <M>.

 -- Function: augcoefmatrix ([<eqn_1>, …, <eqn_m>], [<x_1>, …, <x_n>])

     Returns the augmented coefficient matrix for the variables <x_1>,
     …, <x_n> of the system of linear equations <eqn_1>, …, <eqn_m>.
     This is the coefficient matrix with a column adjoined for the
     constant terms in each equation (i.e., those terms not dependent
     upon <x_1>, …, <x_n>).

          (%i1) m: [2*x - (a - 1)*y = 5*b, c + b*y + a*x = 0]$
          (%i2) augcoefmatrix (m, [x, y]);
                                 [ 2  1 - a  - 5 b ]
          (%o2)                  [                 ]
                                 [ a    b      c   ]

 -- Function: cauchy_matrix
          cauchy_matrix ([<x_1>, <x_2>, …, <x_m>], [<y_1>, <y_2>, …,
          <y_n>])
          cauchy_matrix ([<x_1>, <x_2>, …, <x_n>])

     Returns a ‘n’ by <m> Cauchy matrix with the elements <a[i,j]> =
     1/(<x_i>+<y_i>).  The second argument of ‘cauchy_matrix’ is
     optional.  For this case the elements of the Cauchy matrix are
     <a[i,j]> = 1/(<x_i>+<x_j>).

     Remark: In the literature the Cauchy matrix can be found defined in
     two forms.  A second definition is <a[i,j]> = 1/(<x_i>-<y_i>).

     Examples:

          (%i1) cauchy_matrix([x1, x2], [y1, y2]);
                                [    1        1    ]
                                [ -------  ------- ]
                                [ y1 + x1  y2 + x1 ]
          (%o1)                 [                  ]
                                [    1        1    ]
                                [ -------  ------- ]
                                [ y1 + x2  y2 + x2 ]

          (%i2) cauchy_matrix([x1, x2]);
                                [   1         1    ]
                                [  ----    ------- ]
                                [  2 x1    x2 + x1 ]
          (%o2)                 [                  ]
                                [    1       1     ]
                                [ -------   ----   ]
                                [ x2 + x1   2 x2   ]

 -- Function: charpoly (<M>, <x>)

     Returns the characteristic polynomial for the matrix <M> with
     respect to variable <x>.  That is, ‘determinant (<M> - diagmatrix
     (length (<M>), <x>))’.

          (%i1) a: matrix ([3, 1], [2, 4]);
                                      [ 3  1 ]
          (%o1)                       [      ]
                                      [ 2  4 ]
          (%i2) expand (charpoly (a, lambda));
                                     2
          (%o2)                lambda  - 7 lambda + 10
          (%i3) (programmode: true, solve (%));
          (%o3)               [lambda = 5, lambda = 2]
          (%i4) matrix ([x1], [x2]);
                                       [ x1 ]
          (%o4)                        [    ]
                                       [ x2 ]
          (%i5) ev (a . % - lambda*%, %th(2)[1]);
                                    [ x2 - 2 x1 ]
          (%o5)                     [           ]
                                    [ 2 x1 - x2 ]
          (%i6) %[1, 1] = 0;
          (%o6)                     x2 - 2 x1 = 0
          (%i7) x2^2 + x1^2 = 1;
                                      2     2
          (%o7)                     x2  + x1  = 1
          (%i8) solve ([%th(2), %], [x1, x2]);
                            1               2
          (%o8) [[x1 = - -------, x2 = - -------],
                         sqrt(5)         sqrt(5)

                                                       1             2
                                              [x1 = -------, x2 = -------]]
                                                    sqrt(5)       sqrt(5)

 -- Function: coefmatrix ([<eqn_1>, …, <eqn_m>], [<x_1>, …, <x_n>])

     Returns the coefficient matrix for the variables <x_1>, …, <x_n> of
     the system of linear equations <eqn_1>, …, <eqn_m>.

          (%i1) coefmatrix([2*x-(a-1)*y+5*b = 0, b*y+a*x = 3], [x,y]);
                                           [ 2  1 - a ]
          (%o1)                            [          ]
                                           [ a    b   ]

 -- Function: col (<M>, <i>)

     Returns the <i>’th column of the matrix <M>.  The return value is a
     matrix.

 -- Function: columnvector (<L>)
 -- Function: covect (<L>)

     Returns a matrix of one column and ‘length (<L>)’ rows, containing
     the elements of the list <L>.

     ‘covect’ is a synonym for ‘columnvector’.

     ‘load ("eigen")’ loads this function.

     This is useful if you want to use parts of the outputs of the
     functions in this package in matrix calculations.

     Example:

          (%i1) load ("eigen")$
          Warning - you are redefining the Macsyma function eigenvalues
          Warning - you are redefining the Macsyma function eigenvectors
          (%i2) columnvector ([aa, bb, cc, dd]);
                                       [ aa ]
                                       [    ]
                                       [ bb ]
          (%o2)                        [    ]
                                       [ cc ]
                                       [    ]
                                       [ dd ]

 -- Function: copymatrix (<M>)

     Returns a copy of the matrix <M>.  This is the only way to make a
     copy aside from copying <M> element by element.

     Note that an assignment of one matrix to another, as in ‘m2: m1’,
     does not copy ‘m1’.  An assignment ‘m2 [i,j]: x’ or ‘setelmx(x, i,
     j, m2)’ also modifies ‘m1 [i,j]’.  Creating a copy with
     ‘copymatrix’ and then using assignment creates a separate, modified
     copy.

 -- Function: determinant (<M>)

     Computes the determinant of <M> by a method similar to Gaussian
     elimination.

     The form of the result depends upon the setting of the switch
     ‘ratmx’.

     There is a special routine for computing sparse determinants which
     is called when the switches ‘ratmx’ and ‘sparse’ are both ‘true’.

 -- Option variable: detout
     Default value: ‘false’

     When ‘detout’ is ‘true’, the determinant of a matrix whose inverse
     is computed is factored out of the inverse.

     For this switch to have an effect ‘doallmxops’ and ‘doscmxops’
     should be ‘false’ (see their descriptions).  Alternatively this
     switch can be given to ‘ev’ which causes the other two to be set
     correctly.

     Example:

          (%i1) m: matrix ([a, b], [c, d]);
                                      [ a  b ]
          (%o1)                       [      ]
                                      [ c  d ]
          (%i2) detout: true$
          (%i3) doallmxops: false$
          (%i4) doscmxops: false$
          (%i5) invert (m);
                                    [  d   - b ]
                                    [          ]
                                    [ - c   a  ]
          (%o5)                     ------------
                                     a d - b c

 -- Function: diagmatrix (<n>, <x>)

     Returns a diagonal matrix of size <n> by <n> with the diagonal
     elements all equal to <x>.  ‘diagmatrix (<n>, 1)’ returns an
     identity matrix (same as ‘ident (<n>)’).

     <n> must evaluate to an integer, otherwise ‘diagmatrix’ complains
     with an error message.

     <x> can be any kind of expression, including another matrix.  If
     <x> is a matrix, it is not copied; all diagonal elements refer to
     the same instance, <x>.

 -- Option variable: doallmxops
     Default value: ‘true’

     When ‘doallmxops’ is ‘true’, all operations relating to matrices
     are carried out.  When it is ‘false’ then the setting of the
     individual ‘dot’ switches govern which operations are performed.

 -- Option variable: domxexpt
     Default value: ‘true’

     When ‘domxexpt’ is ‘true’, a matrix exponential, ‘exp (<M>)’ where
     <M> is a matrix, is interpreted as a matrix with element ‘[i,j]’
     equal to ‘exp (m[i,j])’.  Otherwise ‘exp (<M>)’ evaluates to ‘exp
     (<ev(M)>)’.

     ‘domxexpt’ affects all expressions of the form ‘<base>^<power>’
     where <base> is an expression assumed scalar or constant, and
     <power> is a list or matrix.

     Example:

          (%i1) m: matrix ([1, %i], [a+b, %pi]);
                                   [   1    %i  ]
          (%o1)                    [            ]
                                   [ b + a  %pi ]
          (%i2) domxexpt: false$
          (%i3) (1 - c)^m;
                                       [   1    %i  ]
                                       [            ]
                                       [ b + a  %pi ]
          (%o3)                 (1 - c)
          (%i4) domxexpt: true$
          (%i5) (1 - c)^m;
                            [                      %i  ]
                            [    1 - c      (1 - c)    ]
          (%o5)             [                          ]
                            [        b + a         %pi ]
                            [ (1 - c)       (1 - c)    ]

 -- Option variable: domxmxops
     Default value: ‘true’

     When ‘domxmxops’ is ‘true’, all matrix-matrix or matrix-list
     operations are carried out (but not scalar-matrix operations); if
     this switch is ‘false’ such operations are not carried out.

 -- Option variable: domxnctimes
     Default value: ‘false’

     When ‘domxnctimes’ is ‘true’, non-commutative products of matrices
     are carried out.

 -- Option variable: dontfactor
     Default value: ‘[]’

     ‘dontfactor’ may be set to a list of variables with respect to
     which factoring is not to occur.  (The list is initially empty.)
     Factoring also will not take place with respect to any variables
     which are less important, according the variable ordering assumed
     for canonical rational expression (CRE) form, than those on the
     ‘dontfactor’ list.

 -- Option variable: doscmxops
     Default value: ‘false’

     When ‘doscmxops’ is ‘true’, scalar-matrix operations are carried
     out.

 -- Option variable: doscmxplus
     Default value: ‘false’

     When ‘doscmxplus’ is ‘true’, scalar-matrix operations yield a
     matrix result.  This switch is not subsumed under ‘doallmxops’.

 -- Option variable: dot0nscsimp
     Default value: ‘true’

     When ‘dot0nscsimp’ is ‘true’, a non-commutative product of zero and
     a nonscalar term is simplified to a commutative product.

 -- Option variable: dot0simp
     Default value: ‘true’

     When ‘dot0simp’ is ‘true’, a non-commutative product of zero and a
     scalar term is simplified to a commutative product.

 -- Option variable: dot1simp
     Default value: ‘true’

     When ‘dot1simp’ is ‘true’, a non-commutative product of one and
     another term is simplified to a commutative product.

 -- Option variable: dotassoc
     Default value: ‘true’

     When ‘dotassoc’ is ‘true’, an expression ‘(A.B).C’ simplifies to
     ‘A.(B.C)’.

 -- Option variable: dotconstrules
     Default value: ‘true’

     When ‘dotconstrules’ is ‘true’, a non-commutative product of a
     constant and another term is simplified to a commutative product.
     Turning on this flag effectively turns on ‘dot0simp’,
     ‘dot0nscsimp’, and ‘dot1simp’ as well.

 -- Option variable: dotdistrib
     Default value: ‘false’

     When ‘dotdistrib’ is ‘true’, an expression ‘A.(B + C)’ simplifies
     to ‘A.B + A.C’.

 -- Option variable: dotexptsimp
     Default value: ‘true’

     When ‘dotexptsimp’ is ‘true’, an expression ‘A.A’ simplifies to
     ‘A^^2’.

 -- Option variable: dotident
     Default value: 1

     ‘dotident’ is the value returned by ‘X^^0’.

 -- Option variable: dotscrules
     Default value: ‘false’

     When ‘dotscrules’ is ‘true’, an expression ‘A.SC’ or ‘SC.A’
     simplifies to ‘SC*A’ and ‘A.(SC*B)’ simplifies to ‘SC*(A.B)’.

 -- Function: echelon (<M>)

     Returns the echelon form of the matrix <M>, as produced by Gaussian
     elimination.  The echelon form is computed from <M> by elementary
     row operations such that the first non-zero element in each row in
     the resulting matrix is one and the column elements under the first
     one in each row are all zero.

     ‘triangularize’ also carries out Gaussian elimination, but it does
     not normalize the leading non-zero element in each row.

     ‘lu_factor’ and ‘cholesky’ are other functions which yield
     triangularized matrices.

          (%i1) M: matrix ([3, 7, aa, bb], [-1, 8, 5, 2], [9, 2, 11, 4]);
                                 [  3   7  aa  bb ]
                                 [                ]
          (%o1)                  [ - 1  8  5   2  ]
                                 [                ]
                                 [  9   2  11  4  ]
          (%i2) echelon (M);
                            [ 1  - 8  - 5      - 2     ]
                            [                          ]
                            [         28       11      ]
                            [ 0   1   --       --      ]
          (%o2)             [         37       37      ]
                            [                          ]
                            [              37 bb - 119 ]
                            [ 0   0    1   ----------- ]
                            [              37 aa - 313 ]

 -- Function: eigenvalues (<M>)
 -- Function: eivals (<M>)

     Returns a list of two lists containing the eigenvalues of the
     matrix <M>.  The first sublist of the return value is the list of
     eigenvalues of the matrix, and the second sublist is the list of
     the multiplicities of the eigenvalues in the corresponding order.

     ‘eivals’ is a synonym for ‘eigenvalues’.

     ‘eigenvalues’ calls the function ‘solve’ to find the roots of the
     characteristic polynomial of the matrix.  Sometimes ‘solve’ may not
     be able to find the roots of the polynomial; in that case some
     other functions in this package (except ‘innerproduct’,
     ‘unitvector’, ‘columnvector’ and ‘gramschmidt’) will not work.
     Sometimes ‘solve’ may find only a subset of the roots of the
     polynomial.  This may happen when the factoring of the polynomial
     contains polynomials of degree 5 or more.  In such cases a warning
     message is displayed and the only the roots found and their
     corresponding multiplicities are returned.

     In some cases the eigenvalues found by ‘solve’ may be complicated
     expressions.  (This may happen when ‘solve’ returns a
     not-so-obviously real expression for an eigenvalue which is known
     to be real.)  It may be possible to simplify the eigenvalues using
     some other functions.

     The package ‘eigen.mac’ is loaded automatically when ‘eigenvalues’
     or ‘eigenvectors’ is referenced.  If ‘eigen.mac’ is not already
     loaded, ‘load ("eigen")’ loads it.  After loading, all functions
     and variables in the package are available.

 -- Function: eigenvectors (<M>)
 -- Function: eivects (<M>)

     Computes eigenvectors of the matrix <M>.  The return value is a
     list of two elements.  The first is a list of the eigenvalues of
     <M> and a list of the multiplicities of the eigenvalues.  The
     second is a list of lists of eigenvectors.  There is one list of
     eigenvectors for each eigenvalue.  There may be one or more
     eigenvectors in each list.

     ‘eivects’ is a synonym for ‘eigenvectors’.

     The package ‘eigen.mac’ is loaded automatically when ‘eigenvalues’
     or ‘eigenvectors’ is referenced.  If ‘eigen.mac’ is not already
     loaded, ‘load ("eigen")’ loads it.  After loading, all functions
     and variables in the package are available.

     Note that ‘eigenvectors’ internally calls ‘eigenvalues’ to obtain
     eigenvalues.  So, when ‘eigenvalues’ returns a subset of all the
     eigenvalues, the ‘eigenvectors’ returns the corresponding subset of
     the all the eigenvectors, with the same warning displayed as
     ‘eigenvalues’.

     The flags that affect this function are:

     ‘nondiagonalizable’ is set to ‘true’ or ‘false’ depending on
     whether the matrix is nondiagonalizable or diagonalizable after
     ‘eigenvectors’ returns.

     ‘hermitianmatrix’ when ‘true’, causes the degenerate eigenvectors
     of the Hermitian matrix to be orthogonalized using the Gram-Schmidt
     algorithm.

     ‘knowneigvals’ when ‘true’ causes the ‘eigen’ package to assume the
     eigenvalues of the matrix are known to the user and stored under
     the global name ‘listeigvals’.  ‘listeigvals’ should be set to a
     list similar to the output ‘eigenvalues’.

     The function ‘algsys’ is used here to solve for the eigenvectors.
     Sometimes if the eigenvalues are messy, ‘algsys’ may not be able to
     find a solution.  In some cases, it may be possible to simplify the
     eigenvalues by first finding them using ‘eigenvalues’ command and
     then using other functions to reduce them to something simpler.
     Following simplification, ‘eigenvectors’ can be called again with
     the ‘knowneigvals’ flag set to ‘true’.

     See also ‘eigenvalues’.

     Examples:

     A matrix which has just one eigenvector per eigenvalue.

          (%i1) M1: matrix ([11, -1], [1, 7]);
                                     [ 11  - 1 ]
          (%o1)                      [         ]
                                     [ 1    7  ]
          (%i2) [vals, vecs] : eigenvectors (M1);
          (%o2) [[[9 - sqrt(3), sqrt(3) + 9], [1, 1]],
                                  [[[1, sqrt(3) + 2]], [[1, 2 - sqrt(3)]]]]
          (%i3) for i thru length (vals[1]) do disp (val[i] = vals[1][i],
            mult[i] = vals[2][i], vec[i] = vecs[i]);
                                 val  = 9 - sqrt(3)
                                    1

                                      mult  = 1
                                          1

                              vec  = [[1, sqrt(3) + 2]]
                                 1

                                 val  = sqrt(3) + 9
                                    2

                                      mult  = 1
                                          2

                              vec  = [[1, 2 - sqrt(3)]]
                                 2

          (%o3)                         done

     A matrix which has two eigenvectors for one eigenvalue (namely 2).

          (%i1) M1: matrix ([0, 1, 0, 0], [0, 0, 0, 0], [0, 0, 2, 0],
                            [0, 0, 0, 2]);
                                  [ 0  1  0  0 ]
                                  [            ]
                                  [ 0  0  0  0 ]
          (%o1)                   [            ]
                                  [ 0  0  2  0 ]
                                  [            ]
                                  [ 0  0  0  2 ]
          (%i2) [vals, vecs]: eigenvectors (M1);
          (%o2) [[[0, 2], [2, 2]], [[[1, 0, 0, 0]],
                                             [[0, 0, 1, 0], [0, 0, 0, 1]]]]
          (%i3) for i thru length (vals[1]) do disp (val[i] = vals[1][i],
            mult[i] = vals[2][i], vec[i] = vecs[i]);
                                      val  = 0
                                         1

                                      mult  = 2
                                          1

                                vec  = [[1, 0, 0, 0]]
                                   1

                                      val  = 2
                                         2

                                      mult  = 2
                                          2

                         vec  = [[0, 0, 1, 0], [0, 0, 0, 1]]
                            2

          (%o3)                         done

 -- Function: ematrix (<m>, <n>, <x>, <i>, <j>)

     Returns an <m> by <n> matrix, all elements of which are zero except
     for the ‘[<i>, <j>]’ element which is <x>.

 -- Function: entermatrix (<m>, <n>)

     Returns an <m> by <n> matrix, reading the elements interactively.

     If <n> is equal to <m>, Maxima prompts for the type of the matrix
     (diagonal, symmetric, antisymmetric, or general) and for each
     element.  Each response is terminated by a semicolon ‘;’ or dollar
     sign ‘$’.

     If <n> is not equal to <m>, Maxima prompts for each element.

     The elements may be any expressions, which are evaluated.
     ‘entermatrix’ evaluates its arguments.

          (%i1) n: 3$
          (%i2) m: entermatrix (n, n)$

          Is the matrix  1. Diagonal  2. Symmetric  3. Antisymmetric
          4. General
          Answer 1, 2, 3 or 4 :
          1$
          Row 1 Column 1:
          (a+b)^n$
          Row 2 Column 2:
          (a+b)^(n+1)$
          Row 3 Column 3:
          (a+b)^(n+2)$

          Matrix entered.
          (%i3) m;
                          [        3                     ]
                          [ (b + a)      0         0     ]
                          [                              ]
          (%o3)           [                  4           ]
                          [    0      (b + a)      0     ]
                          [                              ]
                          [                            5 ]
                          [    0         0      (b + a)  ]

 -- Function: genmatrix
          genmatrix (<a>, <i_2>, <j_2>, <i_1>, <j_1>)
          genmatrix (<a>, <i_2>, <j_2>, <i_1>)
          genmatrix (<a>, <i_2>, <j_2>)

     Returns a matrix generated from <a>, taking element ‘<a>[<i_1>,
     <j_1>]’ as the upper-left element and ‘<a>[<i_2>, <j_2>]’ as the
     lower-right element of the matrix.  Here <a> is a declared array
     (created by ‘array’ but not by ‘make_array’) or a ‘hashed array’,
     or a ‘memoizing function’, or a lambda expression of two arguments.
     (A ‘memoizing function’ is created like other functions with ‘:=’
     or ‘define’, but arguments are enclosed in square brackets instead
     of parentheses.)

     If <j_1> is omitted, it is assumed equal to <i_1>.  If both <j_1>
     and <i_1> are omitted, both are assumed equal to 1.

     If a selected element ‘i,j’ of the array is undefined, the matrix
     will contain a symbolic element ‘<a>[i,j]’.

     Examples:

          (%i1) h [i, j] := 1 / (i + j - 1);
                                              1
          (%o1)                  h     := ---------
                                  i, j    i + j - 1
          (%i2) genmatrix (h, 3, 3);
                                     [    1  1 ]
                                     [ 1  -  - ]
                                     [    2  3 ]
                                     [         ]
                                     [ 1  1  1 ]
          (%o2)                      [ -  -  - ]
                                     [ 2  3  4 ]
                                     [         ]
                                     [ 1  1  1 ]
                                     [ -  -  - ]
                                     [ 3  4  5 ]
          (%i3) array (a, fixnum, 2, 2);
          (%o3)                           a
          (%i4) a [1, 1] : %e;
          (%o4)                          %e
          (%i5) a [2, 2] : %pi;
          (%o5)                          %pi
          (%i6) genmatrix (a, 2, 2);
                                     [ %e   0  ]
          (%o6)                      [         ]
                                     [ 0   %pi ]
          (%i7) genmatrix (lambda ([i, j], j - i), 3, 3);
                                   [  0    1   2 ]
                                   [             ]
          (%o7)                    [ - 1   0   1 ]
                                   [             ]
                                   [ - 2  - 1  0 ]
          (%i8) genmatrix (B, 2, 2);
                                  [ B      B     ]
                                  [  1, 1   1, 2 ]
          (%o8)                   [              ]
                                  [ B      B     ]
                                  [  2, 1   2, 2 ]

 -- Function: gramschmidt
          gramschmidt (<x>)
          gramschmidt (<x>, <F>)

     Carries out the Gram-Schmidt orthogonalization algorithm on <x>,
     which is either a matrix or a list of lists.  <x> is not modified
     by ‘gramschmidt’.  The inner product employed by ‘gramschmidt’ is
     <F>, if present, otherwise the inner product is the function
     ‘innerproduct’.

     If <x> is a matrix, the algorithm is applied to the rows of <x>.
     If <x> is a list of lists, the algorithm is applied to the
     sublists, which must have equal numbers of elements.  In either
     case, the return value is a list of lists, the sublists of which
     are orthogonal and span the same space as <x>.  If the dimension of
     the span of <x> is less than the number of rows or sublists, some
     sublists of the return value are zero.

     ‘factor’ is called at each stage of the algorithm to simplify
     intermediate results.  As a consequence, the return value may
     contain factored integers.

     ‘load("eigen")’ loads this function.

     Example:

     Gram-Schmidt algorithm using default inner product function.

          (%i1) load ("eigen")$
          (%i2) x: matrix ([1, 2, 3], [9, 18, 30], [12, 48, 60]);
                                   [ 1   2   3  ]
                                   [            ]
          (%o2)                    [ 9   18  30 ]
                                   [            ]
                                   [ 12  48  60 ]
          (%i3) y: gramschmidt (x);
                                 2      2            4     3
                                3      3   3 5      2  3  2  3
          (%o3)  [[1, 2, 3], [- ---, - --, ---], [- ----, ----, 0]]
                                2 7    7   2 7       5     5
          (%i4) map (innerproduct, [y[1], y[2], y[3]], [y[2], y[3], y[1]]);
          (%o4)                       [0, 0, 0]

     Gram-Schmidt algorithm using a specified inner product function.

          (%i1) load ("eigen")$
          (%i2) ip (f, g) := integrate (f * g, u, a, b);
          (%o2)          ip(f, g) := integrate(f g, u, a, b)
          (%i3) y: gramschmidt ([1, sin(u), cos(u)], ip), a=-%pi/2, b=%pi/2;
                                         %pi cos(u) - 2
          (%o3)              [1, sin(u), --------------]
                                              %pi
          (%i4) map (ip, [y[1], y[2], y[3]], [y[2], y[3], y[1]]), a=-%pi/2,
                   b=%pi/2;
          (%o4)                       [0, 0, 0]

 -- Function: ident (<n>)

     Returns an <n> by <n> identity matrix.

 -- Function: innerproduct (<x>, <y>)
 -- Function: inprod (<x>, <y>)

     Returns the inner product (also called the scalar product or dot
     product) of <x> and <y>, which are lists of equal length, or both
     1-column or 1-row matrices of equal length.  The return value is
     ‘conjugate (x) . y’, where ‘.’ is the noncommutative multiplication
     operator.

     ‘load ("eigen")’ loads this function.

     ‘inprod’ is a synonym for ‘innerproduct’.

 -- Function: invert_by_adjoint (<M>)
     Returns the inverse of the matrix <M>.  The inverse is computed by
     the adjoint method.

     ‘invert_by_adjoint’ honors the ‘ratmx’ and ‘detout’ flags, the same
     as ‘invert’.

 -- Function: invert (<M>)

     Returns the inverse of the matrix <M>.  The inverse is computed via
     the LU decomposition.

     When ‘ratmx’ is ‘true’, elements of <M> are converted to canonical
     rational expressions (CRE), and the elements of the return value
     are also CRE.

     When ‘ratmx’ is ‘false’, elements of <M> are not converted to a
     common representation.  In particular, float and bigfloat elements
     are not converted to rationals.

     When ‘detout’ is ‘true’, the determinant is factored out of the
     inverse.  The global flags ‘doallmxops’ and ‘doscmxops’ must be
     ‘false’ to prevent the determinant from being absorbed into the
     inverse.  ‘xthru’ can multiply the determinant into the inverse.

     ‘invert’ does not apply any simplifications to the elements of the
     inverse apart from the default arithmetic simplifications.
     ‘ratsimp’ and ‘expand’ can apply additional simplifications.  In
     particular, when <M> has polynomial elements, ‘expand(invert(<M>))’
     might be preferable.

     ‘invert(<M>)’ is equivalent to ‘<M>^^-1’.

 -- Function: list_matrix_entries (<M>)

     Returns a list containing the elements of the matrix <M>.

     Example:

          (%i1) list_matrix_entries(matrix([a,b],[c,d]));
          (%o1)                     [a, b, c, d]

 -- Option variable: lmxchar
     Default value: ‘[’

     ‘lmxchar’ is the character displayed as the left delimiter of a
     matrix.  See also ‘rmxchar’.

     Example:

          (%i1) lmxchar: "|"$
          (%i2) matrix ([a, b, c], [d, e, f], [g, h, i]);
                                     | a  b  c ]
                                     |         ]
          (%o2)                      | d  e  f ]
                                     |         ]
                                     | g  h  i ]

 -- Function: matrix (<row_1>, …, <row_n>)

     Returns a rectangular matrix which has the rows <row_1>, …,
     <row_n>.  Each row is a list of expressions.  All rows must be the
     same length.

     The operations ‘+’ (addition), ‘-’ (subtraction), ‘*’
     (multiplication), and ‘/’ (division), are carried out element by
     element when the operands are two matrices, a scalar and a matrix,
     or a matrix and a scalar.  The operation ‘^’ (exponentiation,
     equivalently ‘**’) is carried out element by element if the
     operands are a scalar and a matrix or a matrix and a scalar, but
     not if the operands are two matrices.  All operations are normally
     carried out in full, including ‘.’ (noncommutative multiplication).

     Matrix multiplication is represented by the noncommutative
     multiplication operator ‘.’.  The corresponding noncommutative
     exponentiation operator is ‘^^’.  For a matrix ‘<A>’, ‘<A>.<A> =
     <A>^^2’ and ‘<A>^^-1’ is the inverse of <A>, if it exists.
     ‘<A>^^-1’ is equivalent to ‘invert(<A>)’.

     There are switches for controlling simplification of expressions
     involving dot and matrix-list operations.  These are ‘doallmxops’,
     ‘domxexpt’, ‘domxmxops’, ‘doscmxops’, and ‘doscmxplus’.

     There are additional options which are related to matrices.  These
     are: ‘lmxchar’, ‘rmxchar’, ‘ratmx’, ‘listarith’, ‘detout’,
     ‘scalarmatrix’ and ‘sparse’.

     There are a number of functions which take matrices as arguments or
     yield matrices as return values.  See ‘eigenvalues’,
     ‘eigenvectors’, ‘determinant’, ‘charpoly’, ‘genmatrix’, ‘addcol’,
     ‘addrow’, ‘copymatrix’, ‘transpose’, ‘echelon’, and ‘rank’.

     Examples:

        • Construction of matrices from lists.
          (%i1) x: matrix ([17, 3], [-8, 11]);
                                     [ 17   3  ]
          (%o1)                      [         ]
                                     [ - 8  11 ]
          (%i2) y: matrix ([%pi, %e], [a, b]);
                                     [ %pi  %e ]
          (%o2)                      [         ]
                                     [  a   b  ]
        • Addition, element by element.
          (%i3) x + y;
                                [ %pi + 17  %e + 3 ]
          (%o3)                 [                  ]
                                [  a - 8    b + 11 ]
        • Subtraction, element by element.
          (%i4) x - y;
                                [ 17 - %pi  3 - %e ]
          (%o4)                 [                  ]
                                [ - a - 8   11 - b ]
        • Multiplication, element by element.
          (%i5) x * y;
                                  [ 17 %pi  3 %e ]
          (%o5)                   [              ]
                                  [ - 8 a   11 b ]
        • Division, element by element.
          (%i6) x / y;
                                  [ 17       - 1 ]
                                  [ ---  3 %e    ]
                                  [ %pi          ]
          (%o6)                   [              ]
                                  [   8    11    ]
                                  [ - -    --    ]
                                  [   a    b     ]
        • Matrix to a scalar exponent, element by element.
          (%i7) x ^ 3;
                                   [ 4913    27  ]
          (%o7)                    [             ]
                                   [ - 512  1331 ]
        • Scalar base to a matrix exponent, element by element.
          (%i8) exp(y);
                                   [   %pi    %e ]
                                   [ %e     %e   ]
          (%o8)                    [             ]
                                   [    a     b  ]
                                   [  %e    %e   ]
        • Matrix base to a matrix exponent.  This is not carried out
          element by element.  See also ‘matrixexp’.
          (%i9) x ^ y;
                                          [ %pi  %e ]
                                          [         ]
                                          [  a   b  ]
                               [ 17   3  ]
          (%o9)                [         ]
                               [ - 8  11 ]
        • Noncommutative matrix multiplication.
          (%i10) x . y;
                            [ 3 a + 17 %pi  3 b + 17 %e ]
          (%o10)            [                           ]
                            [ 11 a - 8 %pi  11 b - 8 %e ]
          (%i11) y . x;
                          [ 17 %pi - 8 %e  3 %pi + 11 %e ]
          (%o11)          [                              ]
                          [  17 a - 8 b     11 b + 3 a   ]
        • Noncommutative matrix exponentiation.  A scalar base <b> to a
          matrix power <M> is carried out element by element and so
          ‘b^^m’ is the same as ‘b^m’.
          (%i12) x ^^ 3;
                                  [  3833   1719 ]
          (%o12)                  [              ]
                                  [ - 4584  395  ]
          (%i13) %e ^^ y;
                                   [   %pi    %e ]
                                   [ %e     %e   ]
          (%o13)                   [             ]
                                   [    a     b  ]
                                   [  %e    %e   ]
        • A matrix raised to a -1 exponent with noncommutative
          exponentiation is the matrix inverse, if it exists.
          (%i14) x ^^ -1;
                                   [ 11      3  ]
                                   [ ---  - --- ]
                                   [ 211    211 ]
          (%o14)                   [            ]
                                   [  8    17   ]
                                   [ ---   ---  ]
                                   [ 211   211  ]
          (%i15) x . (x ^^ -1);
                                      [ 1  0 ]
          (%o15)                      [      ]
                                      [ 0  1 ]

 -- Function: matrixexp
          matrixexp (<M>)
          matrixexp (<M>, <n>)
          matrixexp (<M>, <V>)

     Calculates the matrix exponential e^(M*V) .  Instead of the vector
     <V> a number <n> can be specified as the second argument.  If this
     argument is omitted ‘matrixexp’ replaces it by ‘1’.

     The matrix exponential of a matrix <M> can be expressed as a power
     series: e^M=sum(M^k/k!,0,inf)

 -- Function: matrixmap (<f>, <M>)

     Returns a matrix with element ‘i,j’ equal to ‘<f>(<M>[i,j])’.

     See also ‘map’, ‘fullmap’, ‘fullmapl’, and ‘apply’.

 -- Function: matrixp (<expr>)

     Returns ‘true’ if <expr> is a matrix, otherwise ‘false’.

 -- Option variable: matrix_element_add
     Default value: ‘+’

     ‘matrix_element_add’ is the operation invoked in place of addition
     in a matrix multiplication.  ‘matrix_element_add’ can be assigned
     any n-ary operator (that is, a function which handles any number of
     arguments).  The assigned value may be the name of an operator
     enclosed in quote marks, the name of a function, or a lambda
     expression.

     See also ‘matrix_element_mult’ and ‘matrix_element_transpose’.

     Example:

          (%i1) matrix_element_add: "*"$
          (%i2) matrix_element_mult: "^"$
          (%i3) aa: matrix ([a, b, c], [d, e, f]);
                                     [ a  b  c ]
          (%o3)                      [         ]
                                     [ d  e  f ]
          (%i4) bb: matrix ([u, v, w], [x, y, z]);
                                     [ u  v  w ]
          (%o4)                      [         ]
                                     [ x  y  z ]
          (%i5) aa . transpose (bb);
                               [  u  v  w   x  y  z ]
                               [ a  b  c   a  b  c  ]
          (%o5)                [                    ]
                               [  u  v  w   x  y  z ]
                               [ d  e  f   d  e  f  ]

 -- Option variable: matrix_element_mult
     Default value: ‘*’

     ‘matrix_element_mult’ is the operation invoked in place of
     multiplication in a matrix multiplication.  ‘matrix_element_mult’
     can be assigned any binary operator.  The assigned value may be the
     name of an operator enclosed in quote marks, the name of a
     function, or a lambda expression.

     The dot operator ‘.’ is a useful choice in some contexts.

     See also ‘matrix_element_add’ and ‘matrix_element_transpose’.

     Example:

          (%i1) matrix_element_add: lambda ([[x]], sqrt (apply ("+", x)))$
          (%i2) matrix_element_mult: lambda ([x, y], (x - y)^2)$
          (%i3) [a, b, c] . [x, y, z];
                                    2          2          2
          (%o3)         sqrt((c - z)  + (b - y)  + (a - x) )
          (%i4) aa: matrix ([a, b, c], [d, e, f]);
                                     [ a  b  c ]
          (%o4)                      [         ]
                                     [ d  e  f ]
          (%i5) bb: matrix ([u, v, w], [x, y, z]);
                                     [ u  v  w ]
          (%o5)                      [         ]
                                     [ x  y  z ]
          (%i6) aa . transpose (bb);
                         [             2          2          2  ]
                         [ sqrt((c - w)  + (b - v)  + (a - u) ) ]
          (%o6)  Col 1 = [                                      ]
                         [             2          2          2  ]
                         [ sqrt((f - w)  + (e - v)  + (d - u) ) ]

                                   [             2          2          2  ]
                                   [ sqrt((c - z)  + (b - y)  + (a - x) ) ]
                           Col 2 = [                                      ]
                                   [             2          2          2  ]
                                   [ sqrt((f - z)  + (e - y)  + (d - x) ) ]

 -- Option variable: matrix_element_transpose
     Default value: ‘false’

     ‘matrix_element_transpose’ is the operation applied to each element
     of a matrix when it is transposed.  ‘matrix_element_mult’ can be
     assigned any unary operator.  The assigned value may be the name of
     an operator enclosed in quote marks, the name of a function, or a
     lambda expression.

     When ‘matrix_element_transpose’ equals ‘transpose’, the ‘transpose’
     function is applied to every element.  When
     ‘matrix_element_transpose’ equals ‘nonscalars’, the ‘transpose’
     function is applied to every nonscalar element.  If some element is
     an atom, the ‘nonscalars’ option applies ‘transpose’ only if the
     atom is declared nonscalar, while the ‘transpose’ option always
     applies ‘transpose’.

     The default value, ‘false’, means no operation is applied.

     See also ‘matrix_element_add’ and ‘matrix_element_mult’.

     Examples:

          (%i1) declare (a, nonscalar)$
          (%i2) transpose ([a, b]);
                                  [ transpose(a) ]
          (%o2)                   [              ]
                                  [      b       ]
          (%i3) matrix_element_transpose: nonscalars$
          (%i4) transpose ([a, b]);
                                  [ transpose(a) ]
          (%o4)                   [              ]
                                  [      b       ]
          (%i5) matrix_element_transpose: transpose$
          (%i6) transpose ([a, b]);
                                  [ transpose(a) ]
          (%o6)                   [              ]
                                  [ transpose(b) ]
          (%i7) matrix_element_transpose: lambda ([x], realpart(x)
                - %i*imagpart(x))$
          (%i8) m: matrix ([1 + 5*%i, 3 - 2*%i], [7*%i, 11]);
                               [ 5 %i + 1  3 - 2 %i ]
          (%o8)                [                    ]
                               [   7 %i       11    ]
          (%i9) transpose (m);
                                [ 1 - 5 %i  - 7 %i ]
          (%o9)                 [                  ]
                                [ 2 %i + 3    11   ]

 -- Function: mattrace (<M>)

     Returns the trace (that is, the sum of the elements on the main
     diagonal) of the square matrix <M>.

     ‘mattrace’ is called by ‘ncharpoly’, an alternative to Maxima’s
     ‘charpoly’.

     ‘load ("nchrpl")’ loads this function.

 -- Function: minor (<M>, <i>, <j>)

     Returns the <i>, <j> minor of the matrix <M>.  That is, <M> with
     row <i> and column <j> removed.

 -- Function: ncharpoly (<M>, <x>)

     Returns the characteristic polynomial of the matrix <M> with
     respect to <x>.  This is an alternative to Maxima’s ‘charpoly’.

     ‘ncharpoly’ works by computing traces of powers of the given
     matrix, which are known to be equal to sums of powers of the roots
     of the characteristic polynomial.  From these quantities the
     symmetric functions of the roots can be calculated, which are
     nothing more than the coefficients of the characteristic
     polynomial.  ‘charpoly’ works by forming the determinant of ‘<x> *
     ident [n] - a’.  Thus ‘ncharpoly’ wins, for example, in the case of
     large dense matrices filled with integers, since it avoids
     polynomial arithmetic altogether.

     ‘load ("nchrpl")’ loads this file.

 -- Function: newdet (<M>)

     Computes the determinant of the matrix <M> by the Johnson-Gentleman
     tree minor algorithm.  ‘newdet’ returns the result in CRE form.

 -- Function: permanent (<M>)

     Computes the permanent of the matrix <M> by the Johnson-Gentleman
     tree minor algorithm.  A permanent is like a determinant but with
     no sign changes.  ‘permanent’ returns the result in CRE form.

     See also ‘newdet’.

 -- Function: rank (<M>)

     Computes the rank of the matrix <M>.  That is, the order of the
     largest non-singular subdeterminant of <M>.

     <rank> may return the wrong answer if it cannot determine that a
     matrix element that is equivalent to zero is indeed so.

 -- Option variable: ratmx
     Default value: ‘false’

     When ‘ratmx’ is ‘false’, determinant and matrix addition,
     subtraction, and multiplication are performed in the representation
     of the matrix elements and cause the result of matrix inversion to
     be left in general representation.

     When ‘ratmx’ is ‘true’, the 4 operations mentioned above are
     performed in CRE form and the result of matrix inverse is in CRE
     form.  Note that this may cause the elements to be expanded
     (depending on the setting of ‘ratfac’) which might not always be
     desired.

 -- Function: row (<M>, <i>)

     Returns the <i>’th row of the matrix <M>.  The return value is a
     matrix.

 -- Option variable: rmxchar
     Default value: ‘]’

     ‘rmxchar’ is the character drawn on the right-hand side of a
     matrix.

     See also ‘lmxchar’.

 -- Option variable: scalarmatrixp
     Default value: ‘true’

     When ‘scalarmatrixp’ is ‘true’, then whenever a 1 x 1 matrix is
     produced as a result of computing the dot product of matrices it is
     simplified to a scalar, namely the sole element of the matrix.

     When ‘scalarmatrixp’ is ‘all’, then all 1 x 1 matrices are
     simplified to scalars.

     When ‘scalarmatrixp’ is ‘false’, 1 x 1 matrices are not simplified
     to scalars.

 -- Function: scalefactors (<coordinatetransform>)

     Here the argument <coordinatetransform> evaluates to the form
     ‘[[expression1, expression2, ...], indeterminate1, indeterminat2,
     ...]’, where the variables <indeterminate1>, <indeterminate2>, etc.
     are the curvilinear coordinate variables and where a set of
     rectangular Cartesian components is given in terms of the
     curvilinear coordinates by ‘[expression1, expression2, ...]’.
     ‘coordinates’ is set to the vector ‘[indeterminate1,
     indeterminate2,...]’, and ‘dimension’ is set to the length of this
     vector.  SF[1], SF[2], …, SF[DIMENSION] are set to the coordinate
     scale factors, and ‘sfprod’ is set to the product of these scale
     factors.  Initially, ‘coordinates’ is ‘[X, Y, Z]’, ‘dimension’ is
     3, and SF[1]=SF[2]=SF[3]=SFPROD=1, corresponding to 3-dimensional
     rectangular Cartesian coordinates.  To expand an expression into
     physical components in the current coordinate system, there is a
     function with usage of the form

 -- Function: setelmx (<x>, <i>, <j>, <M>)

     Assigns <x> to the (<i>, <j>)’th element of the matrix <M>, and
     returns the altered matrix.

     ‘<M> [<i>, <j>]: <x>’ has the same effect, but returns <x> instead
     of <M>.

 -- Function: similaritytransform (<M>)
 -- Function: simtran (<M>)

     ‘similaritytransform’ computes a similarity transform of the matrix
     ‘M’.  It returns a list which is the output of the
     ‘uniteigenvectors’ command.  In addition if the flag
     ‘nondiagonalizable’ is ‘false’ two global matrices ‘leftmatrix’ and
     ‘rightmatrix’ are computed.  These matrices have the property that
     ‘leftmatrix . <M> . rightmatrix’ is a diagonal matrix with the
     eigenvalues of <M> on the diagonal.  If ‘nondiagonalizable’ is
     ‘true’ the left and right matrices are not computed.

     If the flag ‘hermitianmatrix’ is ‘true’ then ‘leftmatrix’ is the
     complex conjugate of the transpose of ‘rightmatrix’.  Otherwise
     ‘leftmatrix’ is the inverse of ‘rightmatrix’.

     ‘rightmatrix’ is the matrix the columns of which are the unit
     eigenvectors of <M>.  The other flags (see ‘eigenvalues’ and
     ‘eigenvectors’) have the same effects since ‘similaritytransform’
     calls the other functions in the package in order to be able to
     form ‘rightmatrix’.

     ‘load ("eigen")’ loads this function.

     ‘simtran’ is a synonym for ‘similaritytransform’.

 -- Option variable: sparse
     Default value: ‘false’

     When ‘sparse’ is ‘true’, and if ‘ratmx’ is ‘true’, then
     ‘determinant’ will use special routines for computing sparse
     determinants.

 -- Function: submatrix
          submatrix (<i_1>, …, <i_m>, <M>, <j_1>, …, <j_n>)
          submatrix (<i_1>, …, <i_m>, <M>)
          submatrix (<M>, <j_1>, …, <j_n>)

     Returns a new matrix composed of the matrix <M> with rows <i_1>, …,
     <i_m> deleted, and columns <j_1>, …, <j_n> deleted.

 -- Function: transpose (<M>)

     Returns the transpose of <M>.

     If <M> is a matrix, the return value is another matrix <N> such
     that ‘N[i,j] = M[j,i]’.

     If <M> is a list, the return value is a matrix <N> of ‘length (m)’
     rows and 1 column, such that ‘N[i,1] = M[i]’.

     Otherwise <M> is a symbol, and the return value is a noun
     expression ‘'transpose (<M>)’.

 -- Function: triangularize (<M>)

     Returns the upper triangular form of the matrix ‘M’, as produced by
     Gaussian elimination.  The return value is the same as ‘echelon’,
     except that the leading nonzero coefficient in each row is not
     normalized to 1.

     ‘lu_factor’ and ‘cholesky’ are other functions which yield
     triangularized matrices.

          (%i1) M: matrix ([3, 7, aa, bb], [-1, 8, 5, 2], [9, 2, 11, 4]);
                                 [  3   7  aa  bb ]
                                 [                ]
          (%o1)                  [ - 1  8  5   2  ]
                                 [                ]
                                 [  9   2  11  4  ]
          (%i2) triangularize (M);
                       [ - 1   8         5            2      ]
                       [                                     ]
          (%o2)        [  0   - 74     - 56         - 22     ]
                       [                                     ]
                       [  0    0    626 - 74 aa  238 - 74 bb ]

 -- Function: uniteigenvectors (<M>)
 -- Function: ueivects (<M>)

     Computes unit eigenvectors of the matrix <M>.  The return value is
     a list of lists, the first sublist of which is the output of the
     ‘eigenvalues’ command, and the other sublists of which are the unit
     eigenvectors of the matrix corresponding to those eigenvalues
     respectively.

     The flags mentioned in the description of the ‘eigenvectors’
     command have the same effects in this one as well.

     When ‘knowneigvects’ is ‘true’, the ‘eigen’ package assumes that
     the eigenvectors of the matrix are known to the user and are stored
     under the global name ‘listeigvects’.  ‘listeigvects’ should be set
     to a list similar to the output of the ‘eigenvectors’ command.

     If ‘knowneigvects’ is set to ‘true’ and the list of eigenvectors is
     given the setting of the flag ‘nondiagonalizable’ may not be
     correct.  If that is the case please set it to the correct value.
     The author assumes that the user knows what he is doing and will
     not try to diagonalize a matrix the eigenvectors of which do not
     span the vector space of the appropriate dimension.

     ‘load ("eigen")’ loads this function.

     ‘ueivects’ is a synonym for ‘uniteigenvectors’.

 -- Function: unitvector (<x>)
 -- Function: uvect (<x>)

     Returns <x>/norm(<x>); this is a unit vector in the same direction
     as <x>.

     ‘load ("eigen")’ loads this function.

     ‘uvect’ is a synonym for ‘unitvector’.

 -- Function: vectorpotential (<givencurl>)

     Returns the vector potential of a given curl vector, in the current
     coordinate system.  ‘potentialzeroloc’ has a similar role as for
     ‘potential’, but the order of the left-hand sides of the equations
     must be a cyclic permutation of the coordinate variables.

 -- Function: vectorsimp (<expr>)

     Applies simplifications and expansions according to the following
     global flags:

     ‘expandall’, ‘expanddot’, ‘expanddotplus’, ‘expandcross’, ‘expandcrossplus’,
     ‘expandcrosscross’, ‘expandgrad’, ‘expandgradplus’, ‘expandgradprod’,
     ‘expanddiv’, ‘expanddivplus’, ‘expanddivprod’, ‘expandcurl’, ‘expandcurlplus’,
     ‘expandcurlcurl’, ‘expandlaplacian’, ‘expandlaplacianplus’,
     and ‘expandlaplacianprod’.

     All these flags have default value ‘false’.  The ‘plus’ suffix
     refers to employing additivity or distributivity.  The ‘prod’
     suffix refers to the expansion for an operand that is any kind of
     product.

     ‘expandcrosscross’
          Simplifies p ~ (q ~ r) to (p . r)*q - (p . q)*r.
     ‘expandcurlcurl’
          Simplifies curl curl p to grad div p + div grad p.
     ‘expandlaplaciantodivgrad’
          Simplifies laplacian p to div grad p.
     ‘expandcross’
          Enables ‘expandcrossplus’ and ‘expandcrosscross’.
     ‘expandplus’
          Enables ‘expanddotplus’, ‘expandcrossplus’, ‘expandgradplus’,
          ‘expanddivplus’, ‘expandcurlplus’, and ‘expandlaplacianplus’.
     ‘expandprod’
          Enables ‘expandgradprod’, ‘expanddivprod’, and
          ‘expandlaplacianprod’.

     These flags have all been declared ‘evflag’.

 -- Option variable: vect_cross
     Default value: ‘false’

     When ‘vect_cross’ is ‘true’, it allows DIFF(X~Y,T) to work where ~
     is defined in SHARE;VECT (where VECT_CROSS is set to ‘true’,
     anyway.)

 -- Function: zeromatrix (<m>, <n>)

     Returns an <m> by <n> matrix, all elements of which are zero.


File: maxima.info,  Node: Пакет affine,  Next: Пакет itensor,  Prev: Matrices and Linear Algebra,  Up: Top

24 Пакет affine
***************

* Menu:

* Введение в пакет affine::      
* Функции и переменные пакета affine::      


File: maxima.info,  Node: Введение в пакет affine,  Next: Функции и переменные пакета affine,  Prev: Пакет affine,  Up: Пакет affine

24.1 Введение в пакет affine
============================

Пакет ‘affine’ предназначен для работы с группами многочленов.


File: maxima.info,  Node: Функции и переменные пакета affine,  Prev: Введение в пакет affine,  Up: Пакет affine

24.2 Функции и переменные пакета affine
=======================================

 -- Функция: fast_linsolve ([<expr_1>, ..., <expr_m>], [<x_1>, ...,
          <x_n>])
     Решает систему линейных уравнений <expr_1>, ..., <expr_m>
     относительно переменных <x_1>, ..., <x_n>.  Каждый аргумент
     <expr_i> может быть уравнением или произвольным выражением.  В
     последнем случае выражение трактуется как уравнение вида ‘<expr_i>
     = 0’.

     Возвращаемое значение является списком вида ‘[<x_1> = <a_1>, ...,
     <x_n> = <a_n>]’, где <a_1>, ..., <a_n> не зависят от переменных
     <x_1>, ..., <x_n>.

     ‘fast_linsolve’ более быстрый чем ‘linsolve’ для разреженных
     систем.

     Команда ‘load("affine")’ загружает эту функцию.

 -- Функция: grobner_basis ([<expr_1>, ..., <expr_m>])
     Возвращает базис Гребнера для уравнений <expr_1>, ..., <expr_m>.
     После этого функция ‘polysimp’ может быть использована для
     упрощения других выражений по функций относительно данной системы
     уравнений.

          grobner_basis ([3*x^2+1, y*x])$

          polysimp (y^2*x + x^3*9 + 2) ==> -3*x + 2

     ‘polysimp(f)’ возвращает 0 тогда и только тогда, когда <f>
     принадлежит идеалу уравнений <expr_1>, ..., <expr_m>.  Иными
     словами, тогда и только тогда, когда <f> является полиномиальной
     комбинацией элементов <expr_1>, ..., <expr_m>.

     Команда ‘load("affine")’ загружает эту функцию.

 -- Функция: set_up_dot_simplifications (<eqns>, <check_through_degree>)
 -- Функция: set_up_dot_simplifications (<eqns>)
     Уравнения <eqns> являются полиномиальными уравнениями относительно
     некоммутативных переменных.  Значение ‘current_variables’ есть
     список переменных, используемых для вычисления степеней.  Уравнения
     должны быть однородными по степеням, для того, чтобы процедура
     сходилась.

     Если перекрывающиеся упрощения в ‘dot_simplifications’ проверены до
     степени выше степени <f>, тогда верно следующее: ‘dotsimp(<f>)’
     дает 0 тогда и только тогда, когда <f> принадлежит идеалу
     уравнений, т.е., тогда и только тогда, когда <f> является
     полиномиальной комбинацией уравнений.

     Здесь степень определяется с помощью ‘nc_degree’ и зависит от весов
     отдельных переменных.

     Команда ‘load("affine")’ загружает эту функцию.

 -- Функция: declare_weights (<x_1>, <w_1>, ..., <x_n>, <w_n>)
     Присваивает веса <w_1>, ..., <w_n> переменным <x_1>, ..., <x_n>.
     Эти веса используются при вычислении ‘nc_degree’.

     Команда ‘load("affine")’ загружает эту функцию.

 -- Функция: nc_degree (<p>)
     Возвращает степень некоммутативного полинома <p>.  См.  также
     ‘declare_weights’.

     Команда ‘load("affine")’ загружает эту функцию.

 -- Функция: dotsimp (<f>)
     Возвращает 0 тогда и только тогда, когда <f> принадлежит идеалу
     уравнений, т.е., тогда и только тогда, когда <f> является
     полиномиальной комбинацией элементов уравнений.

     Команда ‘load("affine")’ загружает эту функцию.

 -- Функция: fast_central_elements ([<x_1>, ..., <x_n>], <n>)
     Если ‘set_up_dot_simplifications’ было уже выполнено, тогда данная
     функция возвращает центральные полиномы степени <n> по переменным
     <x_1>, ..., <x_n>.

     Например:
          set_up_dot_simplifications ([y.x + x.y], 3);
          fast_central_elements ([x, y], 2);
          [y.y, x.x];

     Команда ‘load("affine")’ загружает эту функцию.

 -- Функция: check_overlaps (<n>, <add_to_simps>)
     Проверяет перекрытия до степени <n>, чтобы убедиться, что имеется
     достаточно правил упрощения для каждой степени чтобы ‘dotsimp’
     работало правильно.  Этот процесс может быть ускорен если заранее
     известна размерность пространства мономов.  Если размерность
     конечная и глобальная, тогда следует использовать ‘hilbert’.  Если
     мономиальная размерность неизвестна, то не следут задавать
     ‘rank_function’.  Необязательный третий аргумент ‘reset’, ‘false’
     означает – не следует спрашивать о переопределении объектов.

     Команда ‘load("affine")’ загружает эту функцию.

 -- Функция: mono ([<x_1>, ..., <x_n>], <n>)
     Возвращает список независимых мономов по отношению к текущим
     упрощениям степени <n> по переменным <x_1>, ..., <x_n>.

     Команда ‘load("affine")’ загружает эту функцию.

 -- Функция: monomial_dimensions (<n>)
     Вычисляет ряд Гильберта до степени <n> для текущей алгебры.

     Команда ‘load("affine")’ загружает эту функцию.

 -- Функция: extract_linear_equations ([<p_1>, ..., <p_n>], [<m_1>, ...,
          <m_n>])
     Возвращает список коэффициентов некоммутативных полиномов <p_1>,
     ..., <p_n> некоммутативных мономов <m_1>, ..., <m_n>.  Коэффициенты
     должны быть скалярными.  Для получения списка мономов используется
     ‘list_nc_monomials’.

     Команда ‘load("affine")’ загружает эту функцию.

 -- Функция: list_nc_monomials ([<p_1>, ..., <p_n>])
 -- Функция: list_nc_monomials (<p>)
     Возвращает список некоммутативных мономов полинома <p> или списка
     полиномов <p_1>, ..., <p_n>.

     Команда ‘load("affine")’ загружает эту функцию.

 -- Управляющая переменная: all_dotsimp_denoms
     Значение по умолчанию: ‘false’

     Когда ‘all_dotsimp_denoms’ является списком,то знаменатели,
     встречающиеся при работе ‘dotsimp’, добавляются к этому списку.
     ‘all_dotsimp_denoms’ может быть инициализировано пустым списком
     ‘[]’ перед вызовом ‘dotsimp’.

     По умолчанию ‘dotsimp’ не собирает числители.


File: maxima.info,  Node: Пакет itensor,  Next: Пакет ctensor,  Prev: Пакет affine,  Up: Top

25 Пакет itensor
****************

* Menu:

* Введение в пакет itensor::
* Функции и переменные пакета itensor::


File: maxima.info,  Node: Введение в пакет itensor,  Next: Функции и переменные пакета itensor,  Prev: Пакет itensor,  Up: Пакет itensor

25.1 Введение в пакет itensor
=============================

В Maxima реализованы два различных типа операций над тензорами: операции
над компонентами – пакет ‘ctensor’ и операции с индексами – пакет
‘itensor’.

   ВАЖНОЕ ЗАМЕЧАНИЕ: Пожалуйста, ниже, обратите внимание на нововведения
в системе индексных обозначений для тензоров.

   При операциях с компонентами тензорный объект рассматривается, как
многомерный массив или матрица.  Операции свертки и ковариантного
дифференцирования над такими объектами фактически сводятся к
дифференцированию элементов матрицы и суммированию по повторяющимся
индексам при помощи команды ‘do’.  Полученный результат операций над
компонентами тензора хранится в форме массива или матрицы.

   При операциях с индексами, тензор рассматривается как функция своих
индексов (ковариантных, контравариантных и индексов производной).  В
этом случае результат тензорных операций, например, таких как свертка
или ковариантное дифференцирование, достигается только с помощью
соответствующих манипуляций с индексами, а не с компонентами, которым
они соответствуют.

   Оба подхода к рассмотрению дифференциальных, алгебраических и
аналитических проблем в контексте Римановой геометрии имеют и
преимущества, и недостатки, которые выявляются при рассмотрении
конкретных задач.  Необходимо иметь ввиду следующие специфические
свойства каждого из методов:

   i) Представление тензоров в явном виде через их компоненты делает
‘ctensor’ алгоритмически простым в использовании.  Вычисления метрики,
производных тензоров и инвариантов реализуются непосредственно по
определению.  Однако, несмотря на вычислительную мощь Maxima, в случае
достаточно сложной метрики, внутренние функциональные связи и
координатные зависимости компонент метрики легко могут привести к
чрезвычайно громоздким выражениям, со скрытой структурой.

   ii) В силу специфики способа, при котором тензора и операции над ними
рассматриваются в терминах символьных операций над их индексами,
выражения, вычисления которых в компонентном представлении выглядели бы
громоздко, могут быть иногда сильно упрощены при помощи использования
симметрий тензоров и специальных функций пакета ‘itensor’, использующих
симметрии.  В тоже время, индексное представление тензоров в этом пакете
создает определенные трудности при определении метрики, функций и
вычислении дифференцируемых объектов.

25.1.1 Новые соглашения для обозначения тензорных индексов
----------------------------------------------------------

До настоящего времени, в пакете ‘itensor’ были приняты обозначения,
которые не сохраняли порядок индексов при операциях свертки, например:

     (%i2) imetric(g);
     (%o2)                                done
     (%i3) ishow(g([],[j,k])*g([],[i,l])*a([i,j],[]))$
                                      i l  j k
     (%t3)                           g    g    a
                                                i j
     (%i4) ishow(contract(%))$
                                           k l
     (%t4)                                a

   Этот результат не верен за исключением случая когда тензор ‘a’
симметричен.  Порядок следования индекса теряется при свертке, несмотря
на то, что ‘itensor’ сохраняет порядок индексов внутри каждого набора
ковариантных и контравариантных индексов (в соответствии со свойствами
симметрии).

   Для того, чтобы избежать данной проблемы была предложена новая
система обозначений, которая совместима с существующей.  В данном случае
контравариантные индексы могут быть вставлены в нужную позицию в наборе
ковариантных, но со знаком минус.  Функции типа ‘contract()’ и ‘ishow()’
были модифицированы таким образом, чтобы понимать новые обозначения.

   В данных обозначениях вычисление предыдущего примера дает:

     (%i5) ishow(g([-j,-k],[])*g([-i,-l],[])*a([i,j],[]))$
                                      i l       j k
     (%t5)                           g    a    g
                                           i j
     (%i6) ishow(contract(%))$
                                           l k
     (%t6)                                a

   В настоящий момент, единственной функцией, где новые обозначения
играют существенную роль является ‘lc2kdt’.  Благодаря этому удается
получить корректный результат для тензорного произведения символов
Леви-Чивита, применяя метрический тензор не прибегая к пересортировке
численных индексов обобщенных символов Кронекера.

   Поскольку данные нововведения сделаны относительно недавно, можно
ожидать присутствие ошибок.  Код был достаточно тщательно протестирован,
чтобы убедиться, что ничего не нарушается при использовании старых
обозначений.  В тоже время при работе в новых обозначения шанс получения
ошибки довольно значителен.  Для исправления замеченных ошибок
обращайтесь к разработчикам.

25.1.2 Манипулирование тензорными индексами
-------------------------------------------

Пакет манипулирования тензорными индексами загружается в Maxima командой
‘load("itensor")’.  Доступен ряд демонстрационных программ, которые
загружаются командой ‘demo(tensor)’.

   В этом пакете тензор рассматривается, как функция индексов и их
списков.  Список ковариантных индексов – это первый аргумент индексного
объекта.  Далее идет список контравариантных индексов и индексы
производной.  Списки могут быть пустыми – ‘[]’.  Это говорит об
отсутствии ковариантный или контравариантных индексов тензора.  Таким
образом, ‘g([a,b],[c])’ представляет тензор ‘g’, который имеет 2
ковариантных индекса ‘(a,b)’, один контравариантный – (‘c’) и не имеет
индексов производной.

   Если есть индексы производной, то они добавляются в качестве
дополнительных аргументов после списка контравариантных индексов.  Они
могут быть либо определены пользователем в явном виде, либо получены в
процессе дифференцирования тензора.  Поскольку обычная производная – это
коммутативная операция, то индексы производной по умолчанию сортируются
в алфавитном порядке если флаг ‘iframe_flag’ не равен ‘true’, указывая
на то, что используется тетрадная метрика.  Такой принцип сортировки
делает возможным для Maxima распознать что, например, ‘t([a],[b],i,j)’
есть тоже самое что и ‘t([a],[b],j,i)’.  Дифференцирование индексных
объектов в отношении координат, индексы которых не являются аргументом
этого объекта, в обычной ситуации давало бы ноль, потому, что
по-умолчанию Maxima не знает, что тензор, представляемый в виде функции
по индексам, может неявно зависеть от соответствующей координаты.
Модификация существующей функции ‘diff’ в пакете ‘itensor’ приводит к
тому, что любой индексный объект зависит от любой переменной
дифференцирования пока не объявлено обратное.  Это делает возможным
распространить известное правило суммирования по немым индексам на
индексы производных.  Необходимо отметить, что ‘itensor’ не заложена
возможность для подъема индексов производных и поэтому они всегда
рассматриваются как ковариантные.

   В настоящий момент, все функции направленные на упрощение тензорных
выражений предполагают, что по умолчанию тензор не обладает какими-либо
свойствами симметрии.  Это условие может быть переопределено путем
замены значения флага ‘allsym:false’ на ‘true’.  В этом случае функции
манипулирования индексами будут рассматривать все индексные объекты, как
полностью симметричные по спискам ковариантных и контравариантных
индексов.

   Пакет ‘itensor’ рассматривает тензора, как функциональные объекты.
При манипулировании тензорными уравнениями используются алгебраические
правила, свойства симметрии и свертки.  Кроме того, в ‘itensor’
определены операции ковариантного дифференцирования, а также кривизна и
кручение.  Вычисления могут проводится также и с учетом метрики
подвижных базисов (тетрады) если значение переменной ‘iframe_flag’ равно
‘true’.

   В примере ниже показано как загрузить пакет ‘itensor’, задать имя
метрики и выполнить простые вычисления.

     (%i1) load("itensor");
     (%o1)      /share/tensor/itensor.lisp
     (%i2) imetric(g);
     (%o2)                                done
     (%i3) components(g([i,j],[]),p([i,j],[])*e([],[]))$
     (%i4) ishow(g([k,l],[]))$
     (%t4)                               e p
                                            k l
     (%i5) ishow(diff(v([i],[]),t))$
     (%t5)                                  0
     (%i6) depends(v,t);
     (%o6)                               [v(t)]
     (%i7) ishow(diff(v([i],[]),t))$
                                         d
     (%t7)                               -- (v )
                                         dt   i
     (%i8) ishow(idiff(v([i],[]),j))$
     (%t8)                                v
                                           i,j
     (%i9) ishow(extdiff(v([i],[]),j))$
     (%t9)                             v    - v
                                        j,i    i,j
                                       -----------
                                            2
     (%i10) ishow(liediff(v,w([i],[])))$
                                    %3          %3
     (%t10)                        v   w     + v   w
                                        i,%3    ,i  %3
     (%i11) ishow(covdiff(v([i],[]),j))$
                                                   %4
     (%t11)                        v    - v   ichr2
                                    i,j    %4      i j
     (%i12) ishow(ev(%,ichr2))$
                    %4 %5
     (%t12) v    - g      v   (e p       + e   p     - e p       - e    p
             i,j           %4     j %5,i    ,i  j %5      i j,%5    ,%5  i j

                                              + e p       + e   p    )/2
                                                   i %5,j    ,j  i %5
     (%i13) iframe_flag:true;
     (%o13)                               true
     (%i14) ishow(covdiff(v([i],[]),j))$
                                                  %6
     (%t14)                        v    - v   icc2
                                    i,j    %6     i j
     (%i15) ishow(ev(%,icc2))$
                                                  %6
     (%t15)                        v    - v   ifc2
                                    i,j    %6     i j
     (%i16) ishow(radcan(ev(%,ifc2,ifc1)))$
                  %6 %8                    %6 %8
     (%t16) - (ifg      v   ifb       + ifg      v   ifb       - 2 v
                         %6    j %8 i             %6    i j %8      i,j

                                                  %6 %8
                                             - ifg      v   ifb      )/2
                                                         %6    %8 i j
     (%i17) ishow(canform(s([i,j],[])-s([j,i])))$
     (%t17)                            s    - s
                                        i j    j i
     (%i18) decsym(s,2,0,[sym(all)],[]);
     (%o18)                               done
     (%i19) ishow(canform(s([i,j],[])-s([j,i])))$
     (%t19)                                 0
     (%i20) ishow(canform(a([i,j],[])+a([j,i])))$
     (%t20)                            a    + a
                                        j i    i j
     (%i21) decsym(a,2,0,[anti(all)],[]);
     (%o21)                               done
     (%i22) ishow(canform(a([i,j],[])+a([j,i])))$
     (%t22)                                 0


File: maxima.info,  Node: Функции и переменные пакета itensor,  Prev: Введение в пакет itensor,  Up: Пакет itensor

25.2 Функции и переменные пакета ‘itensor’
==========================================

25.2.1 Манипулирование индексными объектами
-------------------------------------------

 -- Функция: entertensor (<name>)

     это интерактивная функция, которая позволяет создать индексный
     объект с именем <name>, содержащий заданные пользователем списки
     ковариантных и контравариантных индексов и индексы производных.
     Отдельный индекс или список индексов (возможно пустой) считаются
     допустимым вводом (см.  пример в секции ‘covdiff’).

 -- Функция: changename (<old>, <new>, <expr>)

     заменяет имя тензора со старого <old> на новое <new> в выражении
     <expr>.  <old> может быть как простым символом, так и списком в
     форме ‘[<name>, <m>, <n>]’.  В последнем случае переименовываются
     только индексные объекты с именем <name> с <m> ковариантным и <n>
     контравариантным индексами.

 -- Функция: listoftens (<expr>)

     в качестве результата возвращает список всех тензоров выражения
     <expr>.  Например,


          (%i6) ishow(a([i,j],[k])*b([u],[],v)+c([x,y],[])*d([],[])*e)$
                                                   k
          (%t6)                        d e c    + a    b
                                            x y    i j  u,v
          (%i7) ishow(listoftens(%))$
                                         k
          (%t7)                        [a   , b   , c   , d]
                                         i j   u,v   x y

 -- Функция: ishow (<expr>)

     печатает выражение <expr>, содержащее индексные объекты, в виде,
     где ковариантные индексы изображены в нижней позиции, а
     контравариантные в верхней.  Индексы производной изображаются после
     ковариантных индексов и отделены запятой (примеры вывода данной
     функции можно найти практически в любой части этого документа).

 -- Функция: indices (<expr>)

     Возвращает список из двух элементов.  Первый – список свободных
     индексов, не участвующих в свертке, в <expr>.  Второй – список
     немых индексов, участвующих в свертках.  Например,


          (%i1) load("itensor");
          (%o1)      /share/tensor/itensor.lisp
          (%i2) ishow(a([i,j],[k,l],m,n)*b([k,o],[j,m,p],q,r))$
                                          k l      j m p
          (%t2)                          a        b
                                          i j,m n  k o,q r
          (%i3) indices(%);
          (%o3)                 [[l, p, i, n, o, q, r], [k, j, m]]

     Тензорное произведение в котором один и тот же немой индекс
     встречается более чем два раза является синтаксически неправильным.
     При работе с ним Maxima выдаст ошибку.

 -- Функция: rename (<expr>)
 -- Функция: rename (<expr>, <count>)

     Возвращает выражение эквивалентное исходному <expr>, но в котором
     все немые индексы переименованы и пронумерованы.  Имена берутся из
     списка ‘[%1, %2, ...]’.  В качестве опции можно задать номер
     <count> с которого начинается список пронумерованных индексов.  По
     умолчанию немые индексы нумеруются от текущей величины <count>.
     Все немые индексы в произведении встречаются ровно 2 раза.  В
     случае ошибки пользователя, когда в исходном выражении одно и тоже
     имя немого индекса встречается более двух раз, Maxima выдаст ошибку
     и остановит вычисления.  Для суммы тензорных произведений, ‘rename’
     применяется к каждому члену суммы при этом счетчик <count> каждый
     раз обнуляется при переходе к следующему слагаемому.  В этом случае
     функция ‘rename’ может служить для упрощения тензорных выражений.
     Кроме того, если ‘allsym’ равно ‘true’, то индексы сортируются в
     алфавитном порядке.  Если значение ‘flipflag’ равно ‘false’, то
     переименование и сортировка осуществляется относительно порядка
     контравариантных индексов.  В случае если значение ‘flipflag’ равно
     ‘true’ переименование и сортировка производится относительно
     порядка ковариантных индексов.  Часто бывает, что комбинированный
     эффект двух применений ‘rename’ с переменой значения флага
     ‘flipflag’ позволяет существенно упростить исходное выражение.
     Например,


          (%i1) load("itensor");
          (%o1)      /share/tensor/itensor.lisp
          (%i2) allsym:true;
          (%o2)                                true
          (%i3) g([],[%4,%5])*g([],[%6,%7])*ichr2([%1,%4],[%3])*
          ichr2([%2,%3],[u])*ichr2([%5,%6],[%1])*ichr2([%7,r],[%2])-
          g([],[%4,%5])*g([],[%6,%7])*ichr2([%1,%2],[u])*
          ichr2([%3,%5],[%1])*ichr2([%4,%6],[%3])*ichr2([%7,r],[%2]),noeval$
          (%i4) expr:ishow(%)$

                 %4 %5  %6 %7      %3         u          %1         %2
          (%t4) g      g      ichr2      ichr2      ichr2      ichr2
                                   %1 %4      %2 %3      %5 %6      %7 r

                  %4 %5  %6 %7      u          %1         %3         %2
               - g      g      ichr2      ichr2      ichr2      ichr2
                                    %1 %2      %3 %5      %4 %6      %7 r
          (%i5) flipflag:true;
          (%o5)                                true
          (%i6) ishow(rename(expr))$
                 %2 %5  %6 %7      %4         u          %1         %3
          (%t6) g      g      ichr2      ichr2      ichr2      ichr2
                                   %1 %2      %3 %4      %5 %6      %7 r

                  %4 %5  %6 %7      u          %1         %3         %2
               - g      g      ichr2      ichr2      ichr2      ichr2
                                    %1 %2      %3 %4      %5 %6      %7 r
          (%i7) flipflag:false;
          (%o7)                                false
          (%i8) rename(%th(2));
          (%o8)                                  0
          (%i9) ishow(rename(expr))$
                 %1 %2  %3 %4      %5         %6         %7        u
          (%t9) g      g      ichr2      ichr2      ichr2     ichr2
                                   %1 %6      %2 %3      %4 r      %5 %7

                  %1 %2  %3 %4      %6         %5         %7        u
               - g      g      ichr2      ichr2      ichr2     ichr2
                                    %1 %3      %2 %6      %4 r      %5 %7

 -- Управляющая переменная: flipflag
     Значение по умолчанию: ‘false’

     Если значение ‘flipflag’ равно ‘false’, то сортировка и
     переименование индексов осуществляется относительно порядка
     контравариантных индексов, в противном случае – относительно
     порядка ковариантных индексов.  Значение флага ‘flipflag’ влияет на
     результат применения функции ‘rename()’ следующим образом: если
     ‘flipflag’ равно ‘false’ то ‘rename’ формирует список немых
     индексов по списку контравариантных индексов, по мере поступления,
     слева направо (если значение флага равно ‘true’, тогда используется
     список ковариантных индексов).  Первый немой индекс в списке
     переименовывается в ‘%1’, следующий в ‘%2’ и т.д.).  Затем индексы
     сортируются (см.  пример в ‘rename()’).

 -- Функция: defcon (<tensor_1>)
 -- Функция: defcon (<tensor_1>, <tensor_2>, <tensor_3>)
     задает свойства тензорной свертки тензора <tensor_1> с <tensor_3>
     так, что в результате получается <tensor_3> с соответствующими
     индексами.  Если задан единственный аргумент, <tensor_1>, тогда
     свертка любого другого тензора (скажем ‘my_tensor’) с <tensor_1>
     дает тот же тензор (‘my_tensor’), но с новым набором индексов в
     соответствии с операцией свертки.  В этом случае, <tensor_1> может
     быть использован для подъема или опускания индексов.

     Например, пусть ‘imetric:g’, тогда путем ‘defcon(g)’ можно
     реализовать подъем и опускание индексов тензора, сворачивая его с
     метрическим тензором.

     Для одного и того же индексного объекта может быть задано более
     одного правила свертки.  В этом случае, для одинаковых объектов
     используется правило свертки заданное последним.  ‘contractions’
     содержит список индексных объектов с заданными, посредством
     ‘defcon’, правилами свертки.

 -- Функция: remcon (<tensor_1> , ..., <tensor_n>)
     удаляет все правила свертки для объектов <tensor_i>.  ‘remcon(all)’
     удаляет все правила свертки для всех индексных объектов.

 -- Функция: contract (<expr>)

     Выполняет свертку тензорного выражения <expr>, которое само по себе
     может быть произвольной комбинацией сумм и произведений тензоров.
     Правила свертки должны быть предварительно заданы с помощью
     ‘defcon’.  Для наилучших результатов, в выражении <expr>,
     необходимо раскрыть все скобки.  Если коэффициенты при тензорах в
     <expr> не содержат дробей, то наиболее эффективный и быстрый способ
     раскрытия скобок в <expr> состоит в применении функции ‘ratexpand’.
     При этом, флаг ‘gcd’ можно положить равным ‘false’, чтобы программа
     не пыталась искать сокращение множителей, используя GCD алгоритмы.

 -- Функция: indexed_tensor (<tensor>)

     Данная операция необходима всяких раз, когда пользователь
     собирается присвоить новые индексные выражения компонентам тензора
     <tensor>, для которого в системе уже предусмотрено свое индексное
     представление.  Примером могут служить символы Кристоффеля 1-го и
     2-го рода ‘ichr1’, ‘ichr2’, выраженные через компоненты метрики,
     или тензор кривизны Римана ‘icurvature’.  См.  пример в пункте
     ‘icurvature’.

 -- Функция: components (<tensor>, <expr>)

     Данная функция присваивает тензору <tensor> индексное выражение
     <expr>.  Это приводит к тому, что при последующих вычислениях
     индексные выражения <tensor> автоматически заменяются на
     соответствующие <expr>.  <tensor> должен иметь вид
     ‘t([...],[...])’, где каждый из списков может быть пустым.  <expr>
     может быть любым индексным выражением имеющим тот же набор
     свободных индексов (не участвующих в свертке), что и <tensor>.
     Если <expr> содержит свертки, то необходимо быть внимательным в
     выборе значений немых индексов, чтобы избежать повторных немых
     индексов.  В этом случае можно рекомендовать другой способ
     присваивания компонент, заключающийся в использовании конструкций
     ‘defrule’ (см.  пример ниже).  Функция ‘remcomps’ очищает
     использованное ранее определение компонент тензора.

     Важно понимать, что для ‘components’ важна только валентность
     тензора а не порядок индексов.  Присваивание значения
     ‘x([i,-j],[])’, ‘x([-j,i],[])’ или ‘x([i],[j])’ приводит к одному
     результату – значение присваивается тензору с именем ‘x’ и
     валентностью ‘(1,1)’.

     Любому индексному выражению можно присвоить любое другое индексное
     представление и компоненты 4-мя различными способами, 2 способа
     включают использование, рассмотренной выше функции ‘components’:

     1) Присваивание одного индексного выражения другому:


          (%i2) components(g([],[i,j]),e([],[i])*p([],[j]))$
          (%i3) ishow(g([],[i,j]))$
                                                i  j
          (%t3)                                e  p

     2) В виде матрицы компонент:


          (%i6) components(g([i,j],[]),lg);
          (%o6)                                done
          (%i7) ishow(g([i,j],[]))$
          (%t7)                                g
                                                i j
          (%i8) g([3,3],[]);
          (%o8)                                  1
          (%i9) g([4,4],[]);
          (%o9)                                 - 1

     3) Путем определения функции.  В примере ниже, тензор ‘h’ равен
     ‘kdelta’ если ‘h’ имеет одинаковое количество ковариантных и
     контравариантных индексов, а индексы производной отсутствуют.  В
     любом другом случае, тензор ‘h’ равен тензору ‘g’:


          (%i4) h(l1,l2,[l3]):=if length(l1)=length(l2) and length(l3)=0
            then kdelta(l1,l2) else apply(g,append([l1,l2], l3))$
          (%i5) ishow(h([i],[j]))$
                                                    j
          (%t5)                               kdelta
                                                    i
          (%i6) ishow(h([i,j],[k],l))$
                                               k
          (%t6)                               g
                                               i j,l

     4) Последний пример связан с использованием конструкций типа
     ‘defrule’.


          (%i1) load("itensor");
          (%o1)      /share/tensor/itensor.lisp
          (%i2) matchdeclare(l1,listp);
          (%o2)                                done
          (%i3) defrule(r1,m(l1,[]),(i1:idummy(),
                g([l1[1],l1[2]],[])*q([i1],[])*e([],[i1])))$

          (%i4) defrule(r2,m([],l1),(i1:idummy(),
                w([],[l1[1],l1[2]])*e([i1],[])*q([],[i1])))$

          (%i5) ishow(m([i,n],[])*m([],[i,m]))$
                                              i m
          (%t5)                              m    m
                                                   i n
          (%i6) ishow(rename(applyb1(%,r1,r2)))$
                                     %1  %2  %3 m
          (%t6)                     e   q   w     q   e   g
                                                   %1  %2  %3 n


 -- Функция: remcomps (<tensor>)

     Удаляет из системы значения компонент тензора ‘tensor’, присвоенных
     при помощи функции ‘components’.

 -- Функция: showcomps (<tensor>)

     Печатает значение компонент тензора, которые были присвоены с
     помощью ‘components’.  Данная функция особенно полезна в случае,
     когда компоненты тензора были заданы с помощью матрицы, как в
     данном примере:


          (%i1) load("ctensor");
          (%o1)       /share/tensor/ctensor.mac
          (%i2) load("itensor");
          (%o2)      /share/tensor/itensor.lisp
          (%i3) lg:matrix([sqrt(r/(r-2*m)),0,0,0],[0,r,0,0],
                          [0,0,sin(theta)*r,0],[0,0,0,sqrt((r-2*m)/r)]);
                         [         r                                     ]
                         [ sqrt(-------)  0       0              0       ]
                         [      r - 2 m                                  ]
                         [                                               ]
                         [       0        r       0              0       ]
          (%o3)          [                                               ]
                         [       0        0  r sin(theta)        0       ]
                         [                                               ]
                         [                                      r - 2 m  ]
                         [       0        0       0        sqrt(-------) ]
                         [                                         r     ]
          (%i4) components(g([i,j],[]),lg);
          (%o4)                                done
          (%i5) showcomps(g([i,j],[]));
                            [         r                                     ]
                            [ sqrt(-------)  0       0              0       ]
                            [      r - 2 m                                  ]
                            [                                               ]
                            [       0        r       0              0       ]
          (%t5)      g    = [                                               ]
                      i j   [       0        0  r sin(theta)        0       ]
                            [                                               ]
                            [                                      r - 2 m  ]
                            [       0        0       0        sqrt(-------) ]
                            [                                         r     ]
          (%o5)                                false

     Функция ‘showcomps’ может также печатать компоненты тензоров ранга
     выше чем 2.

 -- Функция: idummy ()

     Увеличивает значение счетчика ‘icounter’ немых индексов на 1 и
     возвращает значение индекса в форме ‘%n’, где n это положительное
     целое число.  Применение ‘idummy’ гарантирует, что немые индексы,
     встречающиеся в текущем выражении?  не будут конфликтовать с уже
     использованными (см.  пример в секции ‘indices’).

 -- Управляющая переменная: idummyx
     Значение по умолчанию: ‘%’

     Данная переменная задает приставку (префикс) для генерируемых немых
     индексов (см.  пример в секции ‘indices’).

 -- Управляющая переменная: icounter
     Значение по умолчанию: ‘1’

     Определяет численный суффикс для генерируемого немого индекса.
     Приставка (префикс) определяется переменной ‘idummyx’

 -- Функция: kdelta (<l1>, <l2>)
     Обобщенный символ Кронекера, где <l1> и <l2> – списки ковариантных
     и контравариантных индексов соответственно.  ‘kdelta([i],[j])’
     возвращает обычный дельта-символ Кронекера.  Команда
     ‘ev(<expr>,kdelta)’ вычисляет <expr>, заменяя все конструкции вида
     ‘kdelta([],[])’ (след ‘kdelta’) на размерность многообразия.

     ‘itensor’ также позволяет использование в ‘kdelta()’ c двумя
     ковариантными или двумя контравариантными индексами.  Эта дает
     возможность задать единичную ко(нтра)-вариантную матрицу.  Данная
     конструкция предусмотрена только для целей программирования.
     Следует помнить, что в ‘itensor’ ‘kdelta([i,j],[])’ не является
     разрешенным тензорным объектом.  Будьте готовы,что при операциях с
     ‘kdelta([i,j],[])’ Maxima может пожаловаться на неправильный
     индексный объект и отказаться от дальнейших вычислений.

 -- Функция: kdels (<l1>, <l2>)

     Симметризованная версия обобщенного дельта-символа Кронекера.
     Введена для удобства вычислений.  Свертка выражения с этим тензором
     приводит к его симметризации.  Примеры:


          (%i1) load("itensor");
          (%o1)      /share/tensor/itensor.lisp
          (%i2) kdelta([1,2],[2,1]);
          (%o2)                                 - 1
          (%i3) kdels([1,2],[2,1]);
          (%o3)                                  1
          (%i4) ishow(kdelta([a,b],[c,d]))$
                                       c       d         d       c
          (%t4)                  kdelta  kdelta  - kdelta  kdelta
                                       a       b         a       b
          (%i4) ishow(kdels([a,b],[c,d]))$
                                       c       d         d       c
          (%t4)                  kdelta  kdelta  + kdelta  kdelta
                                       a       b         a       b

 -- Функция: levi_civita (<l>)
     Перестановочный тензор Леви-Чивита, который дает 1 если список <l>
     является четной перестановкой целых чисел, -1 для нечетной
     перестановки, и 0 когда встречаются повторяющиеся индексы.

 -- Функция: lc2kdt (<expr>)
     Приводит к упрощению выражений содержащих символы Леви-Чивита
     (произведения этих символов заменяются на соответствующие
     дельта-символы Кронекера).  Основная разница между действием данной
     функции и непосредственным вычислением перестановочного тензора
     состоит в том, что прямое вычисление тензора Леви-Чивита часто
     приводит к выражениям содержащим дельта-символы с целочисленными
     значения индексов, что затрудняет дальнейшие операции.  Применение
     функции ‘lc2kdt’ позволяет избежать этих проблем.


          (%i1) load("itensor");
          (%o1)      /share/tensor/itensor.lisp
          (%i2) expr:ishow('levi_civita([],[i,j])
                           *'levi_civita([k,l],[])*a([j],[k]))$
                                            i j  k
          (%t2)                  levi_civita    a  levi_civita
                                                 j            k l
          (%i3) ishow(ev(expr,levi_civita))$
                                            i j  k       1 2
          (%t3)                       kdelta    a  kdelta
                                            1 2  j       k l
          (%i4) ishow(ev(%,kdelta))$
                       i       j         j       i   k
          (%t4) (kdelta  kdelta  - kdelta  kdelta ) a
                       1       2         1       2   j

                                         1       2         2       1
                                  (kdelta  kdelta  - kdelta  kdelta )
                                         k       l         k       l
          (%i5) ishow(lc2kdt(expr))$
                               k       i       j    k       j       i
          (%t5)               a  kdelta  kdelta  - a  kdelta  kdelta
                               j       k       l    j       k       l
          (%i6) ishow(contract(expand(%)))$
                                           i           i
          (%t6)                           a  - a kdelta
                                           l           l

     Для использования ‘lc2kdt()’ необходимо задать метрический тензор
     (для случая когда, встречаются произведения перестановочных
     тензоров одинакового ранга и типа).  Если метрика не была задана
     заранее (с помощью ‘imetric’), то можно столкнуться с ошибкой.


          (%i7) expr:ishow('levi_civita([],[i,j])
                           *'levi_civita([],[k,l])*a([j,k],[]))$
                                           i j            k l
          (%t7)                 levi_civita    levi_civita    a
                                                               j k
          (%i8) ishow(lc2kdt(expr))$
          Maxima encountered a Lisp error:

           Error in $IMETRIC [or a callee]:
           $IMETRIC [or a callee] requires less than two arguments.

          Automatically continuing.
          To reenable the Lisp debugger set *debugger-hook* to nil.
          (%i9) imetric(g);
          (%o9)                                done
          (%i10) ishow(lc2kdt(expr))$
                   %3 i       k   %4 j       l     %3 i       l   %4 j
          (%t10) (g     kdelta   g     kdelta   - g     kdelta   g
                              %3             %4               %3
                        k
                  kdelta  ) a
                        %4   j k
          (%i11) ishow(contract(expand(%)))$
                                            l i      l i
          (%t11)                           a    - a g

 -- Функция: lc_l

     Правило упрощения выражений содержащих индексные символы
     Леви-Чивита (‘levi_civita’).  Данное правило преобразования
     использует свойства антисимметрии перестановочного тензора.
     Например:


          (%i1) load("itensor");
          (%o1)      /share/tensor/itensor.lisp
          (%i2)  el1:ishow('levi_civita([i,j,k],[])*a([],[i])*a([],[j]))$
                                       i  j
          (%t2)                       a  a  levi_civita
                                                       i j k
          (%i3) el2:ishow('levi_civita([],[i,j,k])*a([i])*a([j]))$
                                                 i j k
          (%t3)                       levi_civita      a  a
                                                        i  j
          (%i4) ishow(canform(contract(expand(applyb1(el1,lc_l,lc_u)))))$
          (%t4)                                  0
          (%i5) ishow(canform(contract(expand(applyb1(el2,lc_l,lc_u)))))$
          (%t5)                                  0

 -- Функция: lc_u

     Правило упрощения выражений содержащих индексные символы
     Леви-Чивита (‘levi_civita’), аналогично ‘lc_l’, данное правило
     преобразования использует свойства антисимметрии перестановочного
     тензора (см.  пример в секции ‘lc_l’).

 -- Функция: canten (<expr>)
     Функция предназначена для упрощения тензорных выражений путем
     переименования и перестановки немых индексов.  Область применения
     ‘canten’ ограничена.  Данная функция применима только для сумм
     тензорных произведений в которых отсутствуют индексы производной и
     не встречаются символы Леви-Чивита.  Ввиду этих ограничений,
     следует избегать ее использования.  Вместо нее рекомендуется
     применять ‘canform’.

 -- Функция: concan (<expr>)

     Аналогична ‘canten’ но дополнительно производит свертку индексов.

25.2.2 Симметрии тензоров
-------------------------

 -- Управляющая переменная: allsym
     Значение по умолчанию: ‘false’

     Если данной переменной присвоить ‘true’, тогда все индексные
     объекты будут считаться симметричными по всем ковариантным и
     контравариантным индексам.  Если ‘allsym’ равно ‘false’, все
     тензора не имеют никаких свойств симметрии априори, пока симметрии
     не будут объявлены.  Индексы производной предполагаются
     симметричными, до тех пор пока не объявлено, что ‘iframe_flag’
     равен ‘true’.

 -- Функция: decsym (<tensor>, <m>, <n>, [<cov_1>, <cov_2>, ...],
          [<contr_1>, <contr_2>, ...])

     Объявляет свойства симметрии тензора <tensor> по <m> ковариантному
     и <n> контравариантным индексам, где <cov_i> и <contr_i> –
     псевдофункции, выражающие соотношения перестановочных симметрий по
     ковариантным и контравариантным индексам соответственно.  Данные
     псевдофункции записываются в форме ‘symoper(<index_1>, <index_2>,
     ...)’, где переменная ‘symoper’ принимает одно из следующих: ‘sym’,
     ‘anti’ или ‘cyc’, которые означают соответственно, симметрию,
     антисимметрию или цикличность индексов.  Переменная <index_i>
     принимает целочисленные значения и указывает на позицию индекса в
     <tensor>, для которого объявляются свойства симметрии.  Определения
     вида ‘symoper(all)’ также дозволены, означая, что все индексы
     удовлетворяют выбранному свойству симметрии.  Например, рассмотрим
     тензорный объект ‘b’ с 5-ю ковариантными индексами.  Команда
     ‘decsym(b,5,3,[sym(1,2),anti(3,4)],[cyc(all)])’ объявляет ‘b’
     симметричным по первому и второму индексу, антисимметричным по 3 и
     4 ковариантным индексам и циклическим по всем контравариантным
     индексам.  Список декларирующий симметрии может быть пустым.
     Функция ‘canform’ использует декларированные свойства симметрии для
     упрощения тензорных выражений.  Примеры даны ниже.


          (%i1) load("itensor");
          (%o1)      /share/tensor/itensor.lisp
          (%i2) expr:contract( expand( a([i1, j1, k1], [])
                     *kdels([i, j, k], [i1, j1, k1])))$
          (%i3) ishow(expr)$
          (%t3)         a      + a      + a      + a      + a      + a
                         k j i    k i j    j k i    j i k    i k j    i j k
          (%i4) decsym(a,3,0,[sym(all)],[]);
          (%o4)                                done
          (%i5) ishow(canform(expr))$
          (%t5)                              6 a
                                                i j k
          (%i6) remsym(a,3,0);
          (%o6)                                done
          (%i7) decsym(a,3,0,[anti(all)],[]);
          (%o7)                                done
          (%i8) ishow(canform(expr))$
          (%t8)                                  0
          (%i9) remsym(a,3,0);
          (%o9)                                done
          (%i10) decsym(a,3,0,[cyc(all)],[]);
          (%o10)                               done
          (%i11) ishow(canform(expr))$
          (%t11)                        3 a      + 3 a
                                           i k j      i j k
          (%i12) dispsym(a,3,0);
          (%o12)                     [[cyc, [[1, 2, 3]], []]]

 -- Функция: remsym (<tensor>, <m>, <n>)

     Удаляет все свойства симметрии тензора <tensor>, имеющего <m>
     ковариантных и <n> контравариантных индексов.

 -- Функция: canform (<expr>)
 -- Функция: canform (<expr>, <rename>)
     Упрощает выражение <expr>, используя переименование немых индексов
     и сортировку всех индексов с учетом объявленных свойств симметрии.
     Если ‘allsym’ равен ‘true’, тогда все индексные выражения
     подразумеваются симметричными по всем индексам.  В противном случае
     используется свойства , объявленные при помощи ‘decsym’.  Немые
     индексы переименовываются таким же образом, как и при использовании
     ‘rename’.  Следует иметь ввиду, что упрощение громоздких выражений
     может потребовать значительного количества вычислительного времени
     и ресурсов памяти.  Иногда затраты на вычисления можно уменьшить
     если сначала переименовать индексы при помощи ‘rename’.  См.
     примеры в пункте ‘decsym’.  Заметим, что ‘canform’ не всегда
     приводит выражение к простейшей форме.  В тоже время ‘canform’
     всегда возвращает математически корректный результат.

     Если значение второго необязательного параметра <rename> равно
     ‘false’, то переименование не производится.

25.2.3 Операции над индексами тензоров
--------------------------------------

 -- Функция: diff (<expr>, <v_1>, [<n_1>, [<v_2>, <n_2>] ...])
     Стандартная функция дифференцирования Maxima, которая в пакете
     ‘itensor’ имеет дополнительные свойства.  Данная конструкция
     означает взятие производной выражения <expr> по переменной <v_1>,
     <n_1> раз, по <v_2>, <n_2>раз и т.д.  В применении к тензорным
     объектам, функция дифференцирования модифицирована таким образом,
     что ‘v_i’ может иметь целочисленные значения от 1 до ‘dim’.  В этом
     случае дифференцирование выполняется по отношению к ‘v_i’-ому
     элементу списка ‘vect_coords’.  Если ‘vect_coords’ является атомом,
     тогда переменная индексированная именем ‘v_i’ будет использована
     как переменная для дифференцирования.  Это допускает использование
     массива имен координат или индексированных имен типа ‘x[1]’,
     ‘x[2]’, в качестве переменных дифференцирования.

 -- Функция: idiff (<expr>, <v_1>, [<n_1>, [<v_2>, <n_2>] ...])
     Индексное дифференцирование.  В отличие от функции ‘diff’, которая
     дифференцирует в отношении некоторой независимой переменной,
     ‘idiff’ может быть использован при дифференцировании по координате.
     Для индексного объекта, такое дифференцирование добавляет ‘v_i’ к
     индексам производной (он добавляется последовательно к ковариантным
     индексам после запятой).  В дальнейшем индексы производной могут
     сортироваться если переменная ‘iframe_flag’ не равна ‘true’.

     ‘idiff’ можно использовать при дифференцировании детерминанта
     метрического тензора.  Таким образом, если метрика ‘imetric’
     обозначена через ‘g’, тогда ‘idiff(determinant(g),k)’ возвращает
     ‘2*determinant(g)*ichr2([%i,k],[%i])’, где немой индекс ‘%i’
     пробегает соответствующие значения.

 -- Функция: liediff (<v>, <tensor>)

     Вычисляет производную Ли от тензорного выражения <tensor> в
     отношении векторного поля <v>.  <tensor> может быть произвольным
     тензорным объектом, а <v> – имя векторного поля (без индексов).
     Например:


          (%i1) load("itensor");
          (%o1)      /share/tensor/itensor.lisp
          (%i2) ishow(liediff(v,a([i,j],[])*b([],[k],l)))$
                 k    %2            %2          %2
          (%t2) b   (v   a       + v   a     + v   a    )
                 ,l       i j,%2    ,j  i %2    ,i  %2 j

                                    %1  k        %1  k      %1  k
                                + (v   b      - b   v    + v   b   ) a
                                        ,%1 l    ,l  ,%1    ,l  ,%1   i j

 -- Функция: rediff (<ten>)

     Вычисляет все команды ‘idiff’ в выражении <ten>.

 -- Функция: undiff (<expr>)

     Возвращает выражение эквивалентное <expr>, но в котором все
     производные индексных объектов заменяются на не вычисляемую форму
     функции ‘idiff’ с такими аргументами, чтобы при дифференцировании
     получился бы соответствующий индексный объект.  Это бывает полезно,
     когда желательно провести некоторые замены в продифференцированных
     индексных объектах.  После этого дифференцирование выполняется при
     помощи ‘ev(<expr>, idiff)’.

 -- Функция: evundiff

     Эквивалентно применению ‘undiff’, затем ‘ev’ и ‘rediff’.

     При помощи этой функции можно легко вычислять выражения,
     дифференциальную форму которых иначе невозможно вычислить.
     Например, следующее выражение приводит к ошибке:

          (%i1) load("itensor");
          (%o1)      /share/tensor/itensor.lisp
          (%i2) icurvature([i,j,k],[l],m);
          Maxima encountered a Lisp error:

           Error in $ICURVATURE [or a callee]:
           $ICURVATURE [or a callee] requires less than three arguments.

          Automatically continuing.
          To reenable the Lisp debugger set *debugger-hook* to nil.

     Однако, если сначала ввести ‘icurvature’ в не вычисляемой форме, а
     затем применить ‘evundiff’, то получим желаемый результат:

          (%i3) ishow('icurvature([i,j,k],[l],m))$
                                                   l
          (%t3)                          icurvature
                                                   i j k,m
          (%i4) ishow(evundiff(%))$
                       l              l         %1           l           %1
          (%t4) - ichr2        - ichr2     ichr2      - ichr2       ichr2
                       i k,j m        %1 j      i k,m        %1 j,m      i k

                       l              l         %1           l           %1
                + ichr2        + ichr2     ichr2      + ichr2       ichr2
                       i j,k m        %1 k      i j,m        %1 k,m      i j

     ЗАМЕЧАНИЕ: В ранних версиях Maxima, операции производных в
     определениях символов Кристоффеля всегда должны были вводится в не
     вычисляемой форме.  Сейчас это исправлено и надобность в процедуре
     ‘evundiff’ в этом случае отпала.  Например:

          (%i5) imetric(g);
          (%o5)                                done
          (%i6) ishow(ichr2([i,j],[k],l))$
                 k %3
                g     (g         - g         + g        )
                        j %3,i l    i j,%3 l    i %3,j l
          (%t6) -----------------------------------------
                                    2

                                   k %3
                                  g     (g       - g       + g      )
                                   ,l     j %3,i    i j,%3    i %3,j
                                + -----------------------------------
                                                   2

 -- Функция: flush (<expr>, <tensor_1>, <tensor_2>, ...)
     Обнуляет в <expr> все объекты <tensor_i>, не имеющие индексов
     производной.

 -- Функция: flushd (<expr>, <tensor_1>, <tensor_2>, ...)
     Обнуляет в <expr> все объекты <tensor_i>, имеющие индексы
     производной.

 -- Функция: flushnd (<expr>, <tensor>, <n>)
     Обнуляет в <expr> все объекты <tensor>, имеющие <n> и больше
     индексов производной.  Например,


          (%i1) load("itensor");
          (%o1)      /share/tensor/itensor.lisp
          (%i2) ishow(a([i],[J,r],k,r)+a([i],[j,r,s],k,r,s))$
                                          J r      j r s
          (%t2)                          a      + a
                                          i,k r    i,k r s
          (%i3) ishow(flushnd(%,a,3))$
                                               J r
          (%t3)                               a
                                               i,k r

 -- Функция: coord (<tensor_1>, <tensor_2>, ...)

     Дает тензорам <tensor_i> свойства координатного дифференцирования,
     такие что производная контравариантного вектора, имя которого
     совпадает с одним из <tensor_i>, дает дельта-символ Кронекера.
     Например, если ‘coord(x)’, тогда вычисление ‘idiff(x([],[i]),j)’
     дает ‘kdelta([i],[j])’.  ‘coord’ это список всех индексных объектов
     имеющих это свойство.

 -- Функция: remcoord (<tensor_1>, <tensor_2>, ...)

     Удаляет свойства координатного дифференцирования для объектов
     <tensor_i>.  ‘remcoord(all)’ удаляет свойства координатного
     дифференцирования для всех индексных объектов.

 -- Функция: makebox (<expr>)
     Служит для цели аналогичной ‘ishow’.  В дополнение, все
     даламбертианы, встречающиеся в <expr> отображаются символом ‘[]’.
     Например, ‘[]p([m],[n])’ представляет сокращение для
     ‘g([],[i,j])*p([m],[n],i,j)’.

 -- Функция: conmetderiv (<expr>, <tensor>)
     Используется для упрощения выражений, содержащих частные
     производные ковариантных и контравариантных форм метрического
     тензора.  Например, при помощи ‘conmetderiv’ можно связать частные
     производные метрического тензора с символами Кристоффеля:


          (%i1) load("itensor");
          (%o1)      /share/tensor/itensor.lisp
          (%i2) ishow(g([],[a,b],c))$
                                                a b
          (%t2)                                g
                                                ,c
          (%i3) ishow(conmetderiv(%,g))$
                                   %1 b      a       %1 a      b
          (%t3)                 - g     ichr2     - g     ichr2
                                             %1 c              %1 c

 -- Функция: simpmetderiv (<expr>)
 -- Функция: simpmetderiv (<expr> [, <stop>])

     Упрощает выражения, содержащие произведения производных
     метрического тензора.  В частности ‘simpmetderiv’ использует два
     тождества:


             ab        ab           ab                 a
            g   g   + g   g     = (g   g  )   = (kdelta )   = 0
             ,d  bc        bc,d         bc ,d          c ,d

     откуда


             ab          ab
            g   g   = - g   g
             ,d  bc          bc,d

     и


            ab          ab
           g   g     = g   g
            ,j  ab,i    ,i  ab,j

     которое следует из симметрии символов Кристоффеля.

     Функция ‘simpmetderiv’ имеет один необязательный аргумент, который,
     если присутствует, вызывает прекращение работы функции сразу после
     первой успешной подстановки.  Функция ‘simpmetderiv’ использует
     глобальную опцию <flipflag>, которая определяет каким образом
     следует выбирать "канонический" порядок индексов произведения.

     В целом, данные возможности позволяют осуществлять упрощения,
     которые невозможно реализовать другими способами, что
     демонстрируется в следующем примере:


          (%i1) load("itensor");
          (%o1)      /share/tensor/itensor.lisp
          (%i2) imetric(g);
          (%o2)                                done
          (%i3) ishow(g([],[a,b])*g([],[b,c])*g([a,b],[],d)*g([b,c],[],e))$
                                       a b  b c
          (%t3)                       g    g    g      g
                                                 a b,d  b c,e
          (%i4) ishow(canform(%))$

          errexp1 has improper indices
           -- an error.  Quitting.  To debug this try debugmode(true);
          (%i5) ishow(simpmetderiv(%))$
                                       a b  b c
          (%t5)                       g    g    g      g
                                                 a b,d  b c,e
          (%i6) flipflag:not flipflag;
          (%o6)                                true
          (%i7) ishow(simpmetderiv(%th(2)))$
                                         a b  b c
          (%t7)                         g    g    g    g
                                         ,d   ,e   a b  b c
          (%i8) flipflag:not flipflag;
          (%o8)                                false
          (%i9) ishow(simpmetderiv(%th(2),stop))$
                                         a b  b c
          (%t9)                       - g    g    g      g
                                              ,e   a b,d  b c
          (%i10) ishow(contract(%))$
                                              b c
          (%t10)                           - g    g
                                              ,e   c b,d

     См.  также ‘weyl.dem’, для примера совместного применения
     ‘simpmetderiv’ и ‘conmetderiv’ для упрощения тензора Вейля.

 -- Функция: flush1deriv (<expr>, <tensor>)

     Обнуляет все производные первого порядка от <tensor> в <expr>.

25.2.4 Тензоры в искривленном пространстве
------------------------------------------

 -- Функция: imetric (<g>)
 -- Системная переменная: imetric

     Определяет имя метрического тензора, присваивая соответствующее
     значение переменной ‘imetric’, ‘imetric:<g>’.  В дополнение к этому
     программа устанавливает соответствующие свойства свертки для данной
     метрики: ‘defcon(<g>)’, ‘defcon(<g>,<g>,kdelta)’.  По умолчанию
     переменная ‘imetric’ не имеет значения.

 -- Функция: ichr1 ([<i>, <j>, <k>])
     Дает значение символа Кристоффеля первого рода, которое по
     определению равно:

                 (g      + g      - g     )/2 .
                   ik,j     jk,i     ij,k
     Перед тем как использовать явные выражения для символов Кристоффеля
     необходимо определить имя метрического тензора, присвоив
     соответствующее значение переменной ‘imetric’, см.  пример ниже в
     разделе ‘covdiff’.

 -- Функция: ichr2 ([<i>, <j>],[<k>])
     Дает значение символа Кристоффеля 2-го рода, которые по определению
     равны:

                                 ks
             ichr2([i,j],[k]) = g    (g      + g      - g     )/2
                                       is,j     js,i     ij,s

 -- Функция: icurvature ([<i>, <j>, <k>], [<h>])
     Дает выражение для тензора кривизны Римана через символы
     Кристоффеля 2-го рода (‘ichr2’).  Используется следующее
     определение:
                      h             h            h         %1         h
            icurvature     = - ichr2      - ichr2     ichr2    + ichr2
                      i j k         i k,j        %1 j      i k        i j,k
                                      h          %1
                               + ichr2      ichr2
                                      %1 k       i j

 -- Функция: covdiff (<expr>, <v_1>, <v_2>, ...)
     Вычисляет ковариантную производную от <expr> по переменным <v_i>
     используя символы Кристоффеля 2-го рода (‘ichr2’).  Для получения
     явных выражений ковариантной производной через компоненты метрики
     необходимо использовать ‘ev(<expr>,ichr2)’, определив
     предварительно метрический тензор.


          (%i1) load("itensor");
          (%o1)      /share/tensor/itensor.lisp
          (%i2) entertensor()$
          Enter tensor name: a;
          Enter a list of the covariant indices: [i,j];
          Enter a list of the contravariant indices: [k];
          Enter a list of the derivative indices: [];
                                                k
          (%t2)                                a
                                                i j
          (%i3) ishow(covdiff(%,s))$
                       k         %1     k         %1     k
          (%t3)     - a     ichr2    - a     ichr2    + a
                       i %1      j s    %1 j      i s    i j,s

                       k     %1
                + ichr2     a
                       %1 s  i j
          (%i4) imetric:g;

          (%o4)                                  g
          (%i5) ishow(ev(%t3,ichr2))$

                   %1 %4  k
                  g      a     (g       - g       + g      )
                          i %1   s %4,j    j s,%4    j %4,s
          (%t5) - ------------------------------------------
                                      2
              %1 %3  k
             g      a     (g       - g       + g      )
                     %1 j   s %3,i    i s,%3    i %3,s
           - ------------------------------------------
                                 2
              k %2  %1
             g     a    (g        - g        + g       )
                    i j   s %2,%1    %1 s,%2    %1 %2,s     k
           + ------------------------------------------- + a
                                  2                         i j,s

 -- Функция: lorentz_gauge (<expr>)
     Налагает условие Лоренцевой калибровки на все индексные объекты в
     <expr>, приравнивая к нулю те, в которых индекс производной
     совпадает с одним из контравариантных индексов.

 -- Функция: igeodesic_coords (<expr>, <name>)

     Позволяет пользователю обнулить не дифференцированные символы
     Кристоффеля и первые производные метрического тензора в <expr>
     (подразумевая "нормальные" координаты).  Переменная <name> в
     функции ‘igeodesic_coords’ может относится, или к имени метрики
     (если таковая присутствует в явном виде в <expr>), или к имени
     связности в качестве которых используются фиксированные имена
     ‘ichr1’ и (или) ‘ichr2’.  В следующем примере, при помощи
     ‘igeodesic_coords’), проверяется свойство цикличности тензора
     Римана.


          (%i1) load("itensor");
          (%o1)      /share/tensor/itensor.lisp
          (%i2) ishow(icurvature([r,s,t],[u]))$
                       u            u         %1         u
          (%t2) - ichr2      - ichr2     ichr2    + ichr2
                       r t,s        %1 s      r t        r s,t

                                                        u         %1
                                                 + ichr2     ichr2
                                                        %1 t      r s
          (%i3) ishow(igeodesic_coords(%,ichr2))$
                                           u            u
          (%t3)                       ichr2      - ichr2
                                           r s,t        r t,s
          (%i4) ishow(igeodesic_coords(icurvature([r,s,t],[u]),ichr2)+
                      igeodesic_coords(icurvature([s,t,r],[u]),ichr2)+
                      igeodesic_coords(icurvature([t,r,s],[u]),ichr2))$
                       u            u            u            u
          (%t4) - ichr2      + ichr2      + ichr2      - ichr2
                       t s,r        t r,s        s t,r        s r,t

                                                       u            u
                                                - ichr2      + ichr2
                                                       r t,s        r s,t
          (%i5) canform(%);
          (%o5)                                  0

25.2.5 Вычисления в подвижном базисе
------------------------------------

В Maxima существует возможность проводить вычисления с использованием
подвижных базисов в качестве которых можно выбирать, либо
ортонормированный базис типа тетрады либо произвольный базис.

   Для использования подвижного базиса переменной ‘iframe_flag’
необходимо присвоить значение ‘true’.  В этом случае символы Кристоффеля
‘ichr1’ и ‘ichr2’ заменяются более общими коэффициентами связности
‘icc1’ и ‘icc2’ соответственно.  Выражения для ‘covdiff’ и ‘icurvature’
также заменяются более общими.

   Базис определяется двумя тензорами: полем дуального базиса (‘ifri’),
и метрическим тензором ‘ifg’.  Для ортонормированного базиса метрический
тензор совпадает с единичной матрицей или Лоренцевой метрикой для
пространства-времени Минковского.  Дуальный базис определяется базисом
векторов (единичных).  Явный вид дуального базиса и его метрики не
обязателен.  По умолчанию все вычисления проводятся в общем виде без
использования явных выражений для ‘ifri’ и ‘ifg’.

   При ‘iframe_flag’ равном ‘true’, во многих случаях для опускания и
подъема индексов вместо стандартной метрики ‘imetric’ используется
метрика тетрады ‘ifg’.

   ВАЖНО: Присвоение ‘iframe_flag’ значения ‘true’ не отменяет свойства
свертки обычной метрики, определенные ранее командами ‘defcon’ или
‘imetric’.  Если используется тетрадный формализм, то определение
стандартной метрики лучше всего ввести с помощью присвоения
соответствующего имени переменной ‘imetric’.  Команду ‘imetric’ лучше НЕ
использовать.

   Maxima использует поле дуального базиса (‘ifri’) и метрический тензор
‘ifg’ для определения структурных коэффициентов базиса (‘ifc1’ и
‘ifc2’), которые в дальнейшем используются для вычисления коэффициентов
связности (‘icc1’ и ‘icc2’), как показано в следующем примере:


     (%i1) load("itensor");
     (%o1)      /share/tensor/itensor.lisp
     (%i2) iframe_flag:true;
     (%o2)                                true
     (%i3) ishow(covdiff(v([],[i]),j))$
                                    i        i     %1
     (%t3)                         v   + icc2     v
                                    ,j       %1 j
     (%i4) ishow(ev(%,icc2))$
                             %1      i           i        i
     (%t4)                  v   (ifc2     + ichr2    ) + v
                                     %1 j        %1 j     ,j
     (%i5) ishow(ev(%,ifc2))$
                 %1    i %2
                v   ifg     (ifb        - ifb        + ifb       )
                                j %2 %1      %2 %1 j      %1 j %2     i
     (%t5)      -------------------------------------------------- + v
                                        2                             ,j
     (%i6) ishow(ifb([a,b,c]))$
                            %5    %4
     (%t6)               ifr   ifr   (ifri        - ifri       )
                            a     b       c %4,%5       c %5,%4

   Когда переменной ‘iframe_bracket_form’ присвоено ‘false’, то
используется альтернативный метод для вычисления коммутатора тетрады
(‘ifb’).


     (%i8) block([iframe_bracket_form:false],ishow(ifb([a,b,c])))$
                            %7    %6        %6      %7
     (%t8)              (ifr   ifr     - ifr     ifr  ) ifri
                            a     b,%7      a,%7    b       c %6

 -- Функция: iframes ()

     Поскольку в данной версии Maxima свойства свертки для ‘ifr’ и
     ‘ifri’, а также (‘ifb’) определены всегда, то данная функция не
     выполняет никаких действий.

 -- Переменная: ifb

     Скобка тетрады (коммутатор).  Вклад метрического тензора тетрады в
     коэффициенты связности выражается через коммутатор тетрады.


                    - ifb      + ifb      + ifb
                         c a b      b c a      a b c
          ifc1    = --------------------------------
              abc                  2

     Сам по себе коммутатор вычисляется через компоненты тетрады и
     метрический тензор тетрады.  В зависимости от значения
     ‘frame_bracket_form’ вычисление скобки тетрады дает разный
     результат.  При ‘frame_bracket_form’ равном ‘true’ получим:


                    d      e                                      f
          ifb =  ifr    ifr   (ifri      - ifri      - ifri    itr   )
             abc    b      c       a d,e       a e,d       a f    d e


     А при ‘itorsion_flag’ равном ‘true’:

                       e      d        d      e
          ifb    = (ifr    ifr    - ifr    ifr   ) ifri
             abc       b      c,e      b,e    c        a d

 -- Переменная: icc1

     Коэффициенты связности первого рода.  В ‘itensor’, определяется
     как:


          icc1    = ichr1    - ikt1    - inmc1
              abc        abc       abc        abc

     В этом выражении, если ‘iframe_flag’ равно ‘true’, символы
     Кристоффеля ‘ichr1’ заменяются коэффициентами связности тетрады
     ‘ifc1’.  Если ‘itorsion_flag’ равно ‘false’, то ‘ikt1’ опускается.
     ‘ikt1’ опускается и в случае если используется базис тетрады, так
     как кручение уже вычислено, как часть скобки тетрады.  Наконец,
     если ‘inonmet_flag’ равен ‘false’, то ‘inmc1’, также опускается при
     вычислениях.

 -- Переменная: icc2

     Коэффициенты связности второго рода.  В ‘itensor’, определяются
     как,


              c         c        c         c
          icc2   = ichr2   - ikt2   - inmc2
              ab        ab       ab        ab

     В этом выражении, если ‘iframe_flag’ равно ‘true’, символы
     Кристоффеля ‘ichr2’ заменяются коэффициентами связности тетрады
     ‘ifc2’.  Если ‘itorsion_flag’ равно ‘false’, то ‘ikt2’ опускается.
     ‘ikt2’ опускается и в случае, если используется базис тетрады, так
     как кручение уже вычислено, как часть скобки тетрады.  Наконец,
     если ‘inonmet_flag’ равен ‘false’, то ‘inmc2’, также опускается при
     вычислениях.

 -- Переменная: ifc1

     Структурные коэффициенты 1-го рода, известные, также, как
     коэффициенты вращения Риччи.  Этот тензор выражает вклад метрики
     тетрады в коэффициенты связности 1-го рода.  Определяется как:


                    - ifb      + ifb      + ifb
                         c a b      b c a      a b c
          ifc1    = --------------------------------
              abc                   2


 -- Переменная: ifc2

     Структурные коэффициенты 2-го рода.  Получаются сверткой
     структурных коэффициентов 1-го рода и метрики тетрады:


              c       cd
          ifc2   = ifg   ifc1
              ab             abd

 -- Переменная: ifr

     Базис тетрады.  Произведение с дуальным базисом (‘ifri’) дает
     метрику тетрады.

 -- Переменная: ifri

     Дуальный базис тетрады.  Определяется набором векторов.  Вместе с
     тензором тетрадной метрики ‘ifg’ образует основу тетрадного
     формализма реализованного в ‘itensor’.

 -- Переменная: ifg

     Тензор тетрадной метрики.  По умолчанию равен ‘kdelta’.
     Пользователь может определить свой, используя ‘components’.

 -- Переменная: ifgi

     Обратная тетрадная метрика.  Свертка с ‘ifg’ дает ‘kdelta’.

 -- Управляющая переменная: iframe_bracket_form
     Значение по умолчанию: ‘true’

     Определяет метод вычисления скобки тетрады ‘ifb’.

25.2.6 Кручение и неметричность
-------------------------------

Maxima умеет учитывать кручение и неметричность.  Вклад кручения в
коэффициенты связности вычисляется, если ‘itorsion_flag’ равен ‘true’.
Аналогично, компоненты неметричности будут учтены, если ‘inonmet_flag’
равен ‘true’.

 -- Переменная: inm

     Вектор неметричности.  Конформная неметричность определяется через
     ковариантную производную метрического тензора, которая в обычном
     случае равна нулю.  Если ‘inonmet_flag’ равен ‘true’, то вычисление
     ковариантной производной метрики дает:


          g     =- g  inm
           ij;k     ij   k

 -- Переменная: inmc1

     Ковариантная перестановка компонент вектора неметричности.
     Определяется путем:


                     g   inm  - inm  g   - g   inm
                      ab    c      a  bc    ac    b
          inmc1    = ------------------------------
               abc                 2

     В тетрадном формализме вместо ‘g’ используется ‘ifg’.

 -- Переменная: inmc2

     Контравариантная перестановка компонент вектора неметричности.
     Применяется когда ‘inonmet_flag’ равен ‘true’.  Определяется путем:


                                c         c         cd
                    -inm  kdelta  - kdelta  inm  + g   inm  g
               c        a       b         a    b          d  ab
          inmc2   = -------------------------------------------
               ab                        2

     В тетрадном формализме вместо ‘g’ используется ‘ifg’.

 -- Переменная: ikt1

     Ковариантная перестановка тензора кручения.  Вычисляется
     посредством:


                            d           d       d
                    -g   itr  - g    itr   - itr   g
                      ad    cb    bd    ca      ab  cd
          ikt1    = ----------------------------------
              abc                   2

     В тетрадном формализме вместо ‘g’ используется ‘ifg’.

 -- Переменная: ikt2

     Контравариантная перестановка тензора кручения.  Вычисляется
     посредством:


              c     cd
          ikt2   = g   ikt1
              ab           abd

     В тетрадном формализме вместо ‘g’ используется ‘ifg’.

 -- Переменная: itr

     Тензор кручения.  Для метрики с кручением индексы ковариантной
     производной не коммутируют.  Пример:


          (%i1) load("itensor");
          (%o1)      /share/tensor/itensor.lisp
          (%i2) imetric:g;
          (%o2)                                  g
          (%i3) covdiff( covdiff( f( [], []), i), j)
                                - covdiff( covdiff( f( [], []), j), i)$
          (%i4) ishow(%)$
                                             %4              %2
          (%t4)                    f    ichr2    - f    ichr2
                                    ,%4      j i    ,%2      i j
          (%i5) canform(%);
          (%o5)                                  0
          (%i6) itorsion_flag:true;
          (%o6)                                true
          (%i7) covdiff( covdiff( f( [], []), i), j)
                                - covdiff( covdiff( f( [], []), j), i)$
          (%i8) ishow(%)$
                                     %8             %6
          (%t8)             f    icc2    - f    icc2    - f     + f
                             ,%8     j i    ,%6     i j    ,j i    ,i j
          (%i9) ishow(canform(%))$
                                             %1             %1
          (%t9)                     f    icc2    - f    icc2
                                     ,%1     j i    ,%1     i j
          (%i10) ishow(canform(ev(%,icc2)))$
                                             %1             %1
          (%t10)                    f    ikt2    - f    ikt2
                                     ,%1     i j    ,%1     j i
          (%i11) ishow(canform(ev(%,ikt2)))$
                                %2 %1                    %2 %1
          (%t11)          f    g      ikt1       - f    g      ikt1
                           ,%2            i j %1    ,%2            j i %1
          (%i12) ishow(factor(canform(rename(expand(ev(%,ikt1))))))$
                                     %3 %2            %1       %1
                               f    g      g      (itr    - itr   )
                                ,%3         %2 %1     j i      i j
          (%t12)               ------------------------------------
                                                2
          (%i13) decsym(itr,2,1,[anti(all)],[]);
          (%o13)                               done
          (%i14) defcon(g,g,kdelta);
          (%o14)                               done
          (%i15) subst(g,nounify(g),%th(3))$
          (%i16) ishow(canform(contract(%)))$
                                                     %1
          (%t16)                           - f    itr
                                              ,%1    i j

25.2.7 Внешняя алгебра
----------------------

В ‘itensor’ реализованы возможности для операций с полностью
антисимметричными ковариантными тензорными объектами (внешние формы).
Полностью антисимметричное тензорное поле ранга (0,L) соответствует
внешней (дифференциальной) L-форме.  Грассманова алгебра L-форм включает
операции внешнего (косого) произведения.

   Операция внешнего произведения не имеет общепринятого определения.
Некоторые авторы определяют внешнее произведение способом, который
соответствует операции антисимметризации.  Например,

                 a a  - a a
                  i j    j i
      a  /\ a  = -----------
       i     j        2

   В более общем случае, внешнее произведение p-формы и q-формы можно
определить путем:

                            1     k1..kp l1..lq
     A       /\ B       = ------ D              A       B
      i1..ip     j1..jq   (p+q)!  i1..ip j1..jq  k1..kp  l1..lq

   где ‘D’ обозначает дельта-символ Кронекера.

   Другие авторы предпочитают "геометрическое" определение,
соответствующее понятию элемента объема:

     a  /\ a  = a a  - a a
      i     j    i j    j i

   В более общем случае имеем:

                            1    k1..kp l1..lq
     A       /\ B       = ----- D              A       B
      i1..ip     j1..jq   p! q!  i1..ip j1..jq  k1..kp  l1..lq

   С алгебраической точки зрения первое определение выглядит более
естественным для ‘itensor’.  С другой стороны, во многих приложения
более принято следовать "геометрическому" определению.  У пользователя
есть выбор – какое из двух определений использовать.  При
‘igeowedge_flag’ равном ‘false’ (по умолчанию), используется
антисимметризация.  В противном случае применяется "геометрическое"
определение.

 -- Оператор: ~

     Обозначает операцию внешнего произведения.  Это бинарная операция.
     В качестве аргументов можно использовать выражения, включающие
     скаляры, ковариантные тензоры 1-го ранга или антисимметричные
     ковариантные тензоры ранга ‘l’ (предварительно объявленные, как
     антисимметричные по всем ковариантным индексам).

     Результат внешнего произведения контролируется флагом
     ‘igeowedge_flag’.  Например:

          (%i1) load("itensor");
          (%o1)      /share/tensor/itensor.lisp
          (%i2) ishow(a([i])~b([j]))$
                                           a  b  - b  a
                                            i  j    i  j
          (%t2)                            -------------
                                                 2
          (%i3) decsym(a,2,0,[anti(all)],[]);
          (%o3)                                done
          (%i4) ishow(a([i,j])~b([k]))$
                                    a    b  + b  a    - a    b
                                     i j  k    i  j k    i k  j
          (%t4)                     ---------------------------
                                                 3
          (%i5) igeowedge_flag:true;
          (%o5)                                true
          (%i6) ishow(a([i])~b([j]))$
          (%t6)                            a  b  - b  a
                                            i  j    i  j
          (%i7) ishow(a([i,j])~b([k]))$
          (%t7)                     a    b  + b  a    - a    b
                                     i j  k    i  j k    i k  j

 -- Оператор: |

     Бинарная операция, обозначающая "внутреннее" произведение – свертку
     с контравариантным вектором.  При этой операции результат не
     зависит от векторных индексов, участвующих в свертке.  Поэтому
     вектор можно задать только именем.

     В пакете ‘itensor’, "внутренняя" свертка с вектором всегда
     выполняется по первому (в отношении алфавитного порядка) индексу.
     Это позволяет проводить более эффективные упрощения выражений,
     включающих "внутренние" свертки.  Например:

          (%i1) load("itensor");
          (%o1)      /share/tensor/itensor.lisp
          (%i2) decsym(a,2,0,[anti(all)],[]);
          (%o2)                                done
          (%i3) ishow(a([i,j],[])|v)$
                                              %1
          (%t3)                              v   a
                                                  %1 j
          (%i4) ishow(a([j,i],[])|v)$
                                               %1
          (%t4)                             - v   a
                                                   %1 j

     Заметим, что "внутренняя" свертка определена только для полностью
     антисимметричных объектов.  В противном случае результат вычисления
     будет неправильным.

 -- Функция: extdiff (<expr>, <ind>)

     Внешнее дифференцирование <expr> по индексу <ind>.  В ‘itensor’
     оператор внешней производной определен как внешнее произведение
     оператора производной и формы.  Таким образом, результат
     вычисления, также зависит от значения флага ‘igeowedge_flag’.
     Например:

          (%i1) load("itensor");
          (%o1)      /share/tensor/itensor.lisp
          (%i2) ishow(extdiff(v([i]),j))$
                                            v    - v
                                             j,i    i,j
          (%t2)                             -----------
                                                 2
          (%i3) decsym(a,2,0,[anti(all)],[]);
          (%o3)                                done
          (%i4) ishow(extdiff(a([i,j]),k))$
                                     a      - a      + a
                                      j k,i    i k,j    i j,k
          (%t4)                      ------------------------
                                                3
          (%i5) igeowedge_flag:true;
          (%o5)                                true
          (%i6) ishow(extdiff(v([i]),j))$
          (%t6)                             v    - v
                                             j,i    i,j
          (%i7) ishow(extdiff(a([i,j]),k))$
          (%t7)                      a      - a      + a
                                      j k,i    i k,j    i j,k

 -- Функция: hodge (<expr>)

     Вычисляет форму дуальную <expr>.  Например:


          (%i1) load("itensor");
          (%o1)      /share/tensor/itensor.lisp
          (%i2) imetric(g);
          (%o2)                            done
          (%i3) idim(4);
          (%o3)                            done
          (%i4) icounter:100;
          (%o4)                             100
          (%i5) decsym(A,3,0,[anti(all)],[])$

          (%i6) ishow(A([i,j,k],[]))$
          (%t6)                           A
                                           i j k
          (%i7) ishow(canform(hodge(%)))$
                                    %1 %2 %3 %4
                         levi_civita            g        A
                                                 %1 %102  %2 %3 %4
          (%t7)          -----------------------------------------
                                             6
          (%i8) ishow(canform(hodge(%)))$
                           %1 %2 %3 %8            %4 %5 %6 %7
          (%t8) levi_civita            levi_civita            g
                                                               %1 %106
                                       g        g        g      A         /6
                                        %2 %107  %3 %108  %4 %8  %5 %6 %7
          (%i9) lc2kdt(%)$

          (%i10) %,kdelta$

          (%i11) ishow(canform(contract(expand(%))))$
          (%t11)                     - A
                                        %106 %107 %108

 -- Переменная: igeowedge_flag
     Значение по умолчанию: ‘false’

     Контролирует результат вычисления внешнего произведения или внешней
     производной.  При ‘igeowedge_flag’ равном ‘false’ (по умолчанию),
     понятие внешней (дифференциальной) формы соответствует полностью
     антисимметричному ковариантному тензорному полю.  В противном
     случае внешняя форма будет согласована с понятием элемента объема.

25.2.8 Экспорт в TeX
--------------------

В ‘itensor’ имеется некоторая поддержка экспорта тензорных выражений в
формат TeX. Поскольку на базовом уровне Maxima тензорные выражения
представлены как вызов некоторых функций, то вызов команды, ‘tex()’ не
даст желаемого результата.  Для экспорта тензорных выражений в TeX можно
использовать команду ‘tentex’.

 -- Функция: tentex (<expr>)

     Команда экспорта тензорных выражений в TeX. Перед использованием
     необходимо загрузить необходимый подпакет, ‘load("tentex")’.
     Например:


          (%i1) load("itensor");
          (%o1)      /share/tensor/itensor.lisp
          (%i2) load("tentex");
          (%o2)       /share/tensor/tentex.lisp
          (%i3) idummyx:m;
          (%o3)                                  m
          (%i4) ishow(icurvature([j,k,l],[i]))$
                      m1       i           m1       i           i
          (%t4)  ichr2    ichr2     - ichr2    ichr2     - ichr2
                      j k      m1 l        j l      m1 k        j l,k

                                                                i
                                                         + ichr2
                                                                j k,l
          (%i5) tentex(%)$
          $$\Gamma_{j\,k}^{m_1}\,\Gamma_{l\,m_1}^{i}-\Gamma_{j\,l}^{m_1}\,
           \Gamma_{k\,m_1}^{i}-\Gamma_{j\,l,k}^{i}+\Gamma_{j\,k,l}^{i}$$

     Заметим, что данном примере ‘idummyx’ равен ‘m’, для того чтобы
     избежать символов % в TeX-овских выражениях.

     ЗАМЕЧАНИЕ: Текущая версия ‘tentex’ является экспериментальной.

25.2.9 Взаимодействие с пакетом ‘ctensor’
-----------------------------------------

В пакет ‘itensor’ заложены возможности для генерации кода Maxima для
компонент тензорных выражений для последующего использования в
‘ctensor’.  Эта задача выполняется вызовом команды ‘ic_convert()’.

 -- Функция: ic_convert (<eqn>)

     Конвертирует тензорное выражение <eqn> из формата ‘itensor’ в
     компоненты для использования в ‘ctensor’.  При этом суммирование по
     немым индексам выполняется в явном виде, используя соответствующие
     замены индексных объектов в массивы; индексы производной заменяются
     не вычисляемую форму ‘diff’; символы Кристоффеля ‘ichr1’ и ‘ichr2’
     заменяются на ‘lcs’ и ‘mcs’, соответственно и если флаг
     ‘metricconvert’ равен ‘true’, тогда ковариантные (контравариантные)
     выражения для метрического тензора везде заменяется на ‘lg’ (или
     ‘ug’).  Кроме того, для суммирования по всем немым индексам
     вводится ‘do’.  Полученное выражение можно вычислить (загрузив
     предварительно пакет ‘ctensor’), используя ‘ev’.  Пример:

          (%i1) load("itensor");
          (%o1)      /share/tensor/itensor.lisp
          (%i2) eqn:ishow(t([i,j],[k])=f([],[])*g([l,m],[])*a([],[m],j)
                *b([i],[l,k]))$
                                       k        m   l k
          (%t2)                       t    = f a   b    g
                                       i j      ,j  i    l m
          (%i3) ic_convert(eqn);
          (%o3) for i thru dim do (for j thru dim do (
                 for k thru dim do
                  t        : f sum(sum(diff(a , ct_coords ) b
                   i, j, k                   m           j   i, l, k

           g    , l, 1, dim), m, 1, dim)))
            l, m
          (%i4) imetric(g);
          (%o4)                                done
          (%i5) metricconvert:true;
          (%o5)                                true
          (%i6) ic_convert(eqn);
          (%o6) for i thru dim do (for j thru dim do (
                 for k thru dim do
                  t        : f sum(sum(diff(a , ct_coords ) b
                   i, j, k                   m           j   i, l, k

           lg    , l, 1, dim), m, 1, dim)))
             l, m

25.2.10 Зарезервированные имена переменных
------------------------------------------

Следующие имена переменных зарезервированы для использования в пакете
‘itensor’.  Следует избегать их переопределения.


       Имя        Комментарий
       ------------------------------------------
       indices2() Внутренняя версия indices()
       conti      Список контравариантных индексов
       covi       Список ковариантных индексов
       deri       Список индексов производной
       name       Возвращает имя индексного объекта
       concan
       irpmon
       lc0
       _lc2kdt0
       _lcprod
       _extlc

25.2.11 Замечания разработчика
------------------------------

Я (Viktor Toth) добавил поддержку тетрадного формализма, кручения и
неметричности в ‘itensor’ в ноябре, 2004.  Эти возможности были
реконструированы на основе описаний данных в руководстве коммерческой
версии Macsyma, а также с использованием результатов исполнения
демонстрационных файлов Macsyma.

   Данная функциональность должна рассматриваться как экспериментальная.
Следует учесть, что доступная документация Macsyma содержала несколько
очевидных ошибок, например, неправильные комбинации индексов.  Кроме
того, результаты демонстрационных расчетов показали, что
функциональность тетрадного формализма в Macsyma далеко не полна.  Моей
цель состоит не в том, чтобы механически воспроизвести все возможности
Macsyma, включая ошибки, а в том, чтобы в итоге получить математически
корректную поддержку данных видов вычислений в ‘itensor’.  Выполнение
этой задачи займет некоторое время.


File: maxima.info,  Node: Пакет ctensor,  Next: Пакет atensor,  Prev: Пакет itensor,  Up: Top

26 Пакет ctensor
****************

* Menu:

* Введение в пакет ctensor::
* Функции и переменные пакета ctensor::


File: maxima.info,  Node: Введение в пакет ctensor,  Next: Функции и переменные пакета ctensor,  Prev: Пакет ctensor,  Up: Пакет ctensor

26.1 Введение в пакет ctensor
=============================

Пакет ‘ctensor’ предназначен для операций с компонентами тензоров.  Для
загрузки ‘ctensor’ необходимо ввести команду ‘load("ctensor")’.
Стандартная интерактивная сессия в ‘ctensor’ начинается с команды
‘csetup()’.  После этого пользователь запрашивается о размерности
многообразия.  Если размерность равна 2, 3 или 4, тогда список координат
по умолчанию устанавливается равным ‘[x,y]’, ‘[x,y,z]’ или ‘[x,y,z,t]’
соответственно.  Имена координат могут быть изменены присваиванием
нового списка координат переменной ‘ct_coords’ (см.  ниже), пользователь
также запрашивается о необходимости переопределения списка координат.
Следует внимательно выбирать имена координат таким образом, чтобы
избежать конфликтов с другими объектами.

   После этого пользователь задает метрику непосредственно, либо
указывая файл в котром она находится.  Файл ‘share/tensor/metrics.mac’
содержит определения некоторых стандартных метрик.  Метрика хранится в
матрице ‘lg’.  Обратная метрика вычисляется и помещается в матрицу ‘ug’.
При определении метрики существует возможность использования степенных
рядов.

   Ниже приведено начало протокола определения статической,
сферически-симметричной метрики (стандартные координаты) с целью
вычисления вакуумных уравнений Эйнштейна, приводящих к решению
Шварцшильда.  Многие функции пакета ‘ctensor’ будут продемонстрированы
на примере этой метрики.

     (%i1) load("ctensor");
     (%o1)      /usr/local/lib/maxima/share/tensor/ctensor.mac
     (%i2) csetup();
     Enter the dimension of the coordinate system:
     4;
     Do you wish to change the coordinate names?
     n;
     Do you want to
     1. Enter a new metric?

     2. Enter a metric from a file?

     3. Approximate a metric with a Taylor series?
     1;

     Is the matrix  1. Diagonal  2. Symmetric  3. Antisymmetric  4. General
     Answer 1, 2, 3 or 4
     1;
     Row 1 Column 1:
     a;
     Row 2 Column 2:
     x^2;
     Row 3 Column 3:
     x^2*sin(y)^2;
     Row 4 Column 4:
     -d;

     Matrix entered.
     Enter functional dependencies with the DEPENDS function or 'N' if none
     depends([a,d],x);
     Do you wish to see the metric?
     y;
                               [ a  0       0        0  ]
                               [                        ]
                               [     2                  ]
                               [ 0  x       0        0  ]
                               [                        ]
                               [         2    2         ]
                               [ 0  0   x  sin (y)   0  ]
                               [                        ]
                               [ 0  0       0       - d ]
     (%o2)                                done
     (%i3) christof(mcs);
                                                 a
                                                  x
     (%t3)                          mcs        = ---
                                       1, 1, 1   2 a

                                                  1
     (%t4)                           mcs        = -
                                        1, 2, 2   x

                                                  1
     (%t5)                           mcs        = -
                                        1, 3, 3   x

                                                 d
                                                  x
     (%t6)                          mcs        = ---
                                       1, 4, 4   2 d

                                                   x
     (%t7)                          mcs        = - -
                                       2, 2, 1     a

                                                cos(y)
     (%t8)                         mcs        = ------
                                      2, 3, 3   sin(y)

                                                    2
                                               x sin (y)
     (%t9)                      mcs        = - ---------
                                   3, 3, 1         a

     (%t10)                   mcs        = - cos(y) sin(y)
                                 3, 3, 2

                                                 d
                                                  x
     (%t11)                         mcs        = ---
                                       4, 4, 1   2 a
     (%o11)                               done


File: maxima.info,  Node: Функции и переменные пакета ctensor,  Prev: Введение в пакет ctensor,  Up: Пакет ctensor

26.2 Функции и переменные пакета ctensor
========================================

26.2.1 Начальные установки
--------------------------

 -- Функция: csetup ()
     Эта функция производит начальные установки пакета ‘ctensor’ и
     позволяет пользователю ввести метрику интерактивно.  См.  ‘ctensor’
     для более подробного описания.

 -- Функция: cmetric (<dis>)
 -- Функция: cmetric ()
     Функция пакета ‘ctensor’, которая вычисляет обратную метрику и
     готовит пакет к проведению дальнейших вычислений.

     Если переключатель ‘cframe_flag’ равен ‘false’, то функция
     вычисляет обратную метрику ‘ug’ исходя из заданной пользователем
     матрицы ‘lg’.  Определитель метрики тоже вычисляется и сохраняется
     в переменной ‘gdet’.  Боле того, программа определяет является ли
     метрика диагональной и соответственным образом устанавливает
     значение ключа ‘diagmetric’.  Если задан необязательный ключ <dis>
     и его значение не равно ‘false’, то в ходе сессии пользователь
     запрашивается требуется ли распечатать компоненты обратной метрики
     на экран.

     Если ключ ‘cframe_flag’ равен ‘true’, тогда ожидается, что заданы
     значения ‘fri’ (матрица обратного базиса) и массив ‘lfg’ (метрика
     относительно данного базиса).  Исходя из этих данных вычисляются
     матрица ‘fr’ и обратная метрика ‘ufg’ относительно заданного
     базиса.

 -- Функция: ct_coordsys (<coordinate_system>, <extra_arg>)
 -- Функция: ct_coordsys (<coordinate_system>)
     Задает одну из предопределенных координатных систем и метрик.
     Аргумент <coordinate_system> может принимать одно из следующих
     значений:


           Символ               Dim Координаты        Описание/комментарии
           ------------------------------------------------------------------
           cartesian2d           2  [x,y]             Декартовы 2D координаты
           polar                 2  [r,phi]           Полярные координаты
           elliptic              2  [u,v]             Эллиптические
                                                      координаты
           confocalelliptic      2  [u,v]             Конфокальные
                                                      эллиптические
           bipolar               2  [u,v]             Биполярные координаты
           parabolic             2  [u,v]             Параболические
                                                      координаты
           cartesian3d           3  [x,y,z]           Декартова 3D система
                                                      координат
           polarcylindrical      3  [r,theta,z]       Цилиндрические
                                                      координаты
           ellipticcylindrical   3  [u,v,z]           Эллиптические 2D
                                                      с цилинром z
           confocalellipsoidal   3  [u,v,w]           Конфокальные
                                                      эллипсоидальные
           bipolarcylindrical    3  [u,v,z]           Биполярные 2D
                                                      с цилиндром z
           paraboliccylindrical  3  [u,v,z]           Параболические 2D
                                                      с цилиндром z
           paraboloidal          3  [u,v,phi]         Параболоидные
                                                      координаты
           conical               3  [u,v,w]           Конические координаты
           toroidal              3  [u,v,phi]         Тороидальные координаты
           spherical             3  [r,theta,phi]     Сферические координаты
           oblatespheroidal      3  [u,v,phi]         Сжатые сфероидальные
           oblatespheroidalsqrt  3  [u,v,phi]
           prolatespheroidal     3  [u,v,phi]         Вытянутые сфероидальные
           prolatespheroidalsqrt 3  [u,v,phi]
           ellipsoidal           3  [r,theta,phi]     Эллипсоидальные
                                                      координаты
           cartesian4d           4  [x,y,z,t]         Декартовы 4D координаты
           spherical4d           4  [r,theta,eta,phi] Сферические 4D
                                                      координаты
           exteriorschwarzschild 4  [t,r,theta,phi]   Метрика Шварцшильда
           interiorschwarzschild 4  [t,z,u,v]         Внутреняя метрика
                                                      Шрарцшильда
           kerr_newman           4  [t,r,theta,phi]   Метрика Керра-Ньюмана

     ‘coordinate_system’ может быть списком функций преобразования, за
     которым следует список координат.  Например, можно задать метрику
     следующим образом:


          (%i1) load("ctensor");
          (%o1)       /share/tensor/ctensor.mac
          (%i2) ct_coordsys([r*cos(theta)*cos(phi),r*cos(theta)*sin(phi),
                r*sin(theta),[r,theta,phi]]);
          (%o2)                                done
          (%i3) lg:trigsimp(lg);
                                     [ 1  0         0        ]
                                     [                       ]
                                     [     2                 ]
          (%o3)                      [ 0  r         0        ]
                                     [                       ]
                                     [         2    2        ]
                                     [ 0  0   r  cos (theta) ]
          (%i4) ct_coords;
          (%o4)                           [r, theta, phi]
          (%i5) dim;
          (%o5)                                  3

     Функции преобразования могут также использоваться и в случае, когда
     ‘cframe_flag’ равно ‘true’:


          (%i1) load("ctensor");
          (%o1)       /share/tensor/ctensor.mac
          (%i2) cframe_flag:true;
          (%o2)                                true
          (%i3) ct_coordsys([r*cos(theta)*cos(phi),r*cos(theta)*sin(phi),
                r*sin(theta),[r,theta,phi]]);
          (%o3)                                done
          (%i4) fri;
          (%o4)
           [cos(phi)cos(theta) -cos(phi) r sin(theta) -sin(phi) r cos(theta)]
           [                                                                ]
           [sin(phi)cos(theta) -sin(phi) r sin(theta)  cos(phi) r cos(theta)]
           [                                                                ]
           [    sin(theta)           r cos(theta)                0          ]

          (%i5) cmetric();
          (%o5)                                false
          (%i6) lg:trigsimp(lg);
                                     [ 1  0         0        ]
                                     [                       ]
                                     [     2                 ]
          (%o6)                      [ 0  r         0        ]
                                     [                       ]
                                     [         2    2        ]
                                     [ 0  0   r  cos (theta) ]

     Необязательный аргумент <extra_arg> может принимать одно из
     следующих значений:

     ‘cylindrical’ указывает ‘ct_coordsys’ добавить одну дополнительную
     цилиндрическую координату.

     ‘minkowski’ указывает ‘ct_coordsys’ добавить дополнительную
     декартову координату с отрицательной сигнатурой.

     ‘all’ указывает ‘ct_coordsys’, что после определения метрики
     необходимо вызвать ‘cmetric’ и ‘christof(false)’.

     Если глобальная переменная ‘verbose’ равна ‘true’, то ‘ct_coordsys’
     выводит значения ‘dim’, ‘ct_coords’, и или ‘lg’ или ‘lfg’ и ‘fri’,
     в зависимости от значения ‘cframe_flag’.

 -- Функция: init_ctensor ()
     Инициализирует пакет ‘ctensor’.

     Функция ‘init_ctensor’ ре-инициализирует пакет ‘ctensor’, при этом
     из памяти удаляются все использованные ранее пакетом ‘ctensor’
     массивы и матрицы и восстанавливаются стандартные значения всех
     ключей, в том числе: размерность многообразия, ‘dim’,
     устанавливается равной 4, а метрика устанавливается равной метрике
     Лоренца.

26.2.2 Тензоры искривленного пространства
-----------------------------------------

Основное назначение пакета ‘ctensor’ – вычисление различных тензоров для
искривленного пространства-времени, в основном тензоров, использующихся
в общей теории относительности.

   При использовании голономного (координатного) базиса ‘ctensor’ может
вычислить следующие объекты:


      lg  -- ug
        \      \
         lcs -- mcs -- ric -- uric
                   \      \       \
                    \      tracer - ein -- lein
                     \
                      riem -- lriem -- weyl
                          \
                           uriem


   ‘ctensor’ может также работать при неголономном базисе (тетрадный
формализм).  Когда ‘cframe_flag’ равно ‘true’, следующие объекты могут
быть вычислены:


      lfg -- ufg
          \
      fri -- fr -- lcs -- mcs -- lriem -- ric -- uric
           \                       |  \      \       \
            lg -- ug               |   weyl   tracer - ein -- lein
                                   |\
                                   | riem
                                   |
                                   \uriem

 -- Функция: christof (<dis>)
     Функция пакета ‘ctensor’, вычисляющая символы Кристоффеля первого и
     второго родов.  Аргумент <dis> определяет какой результат должен
     быть отображен.  Символы Кристоффеля первого и второго рода
     хранятся в массивах ‘lcs[i,j,k]’ и ‘mcs[i,j,k]’ соответственно и
     считается симметричным по первой паре индексов.  Если аргумент
     ‘christof’ есть ‘lcs’ или ‘mcs’ то будут выведены все уникальные
     (симметрия) ненулевые значения ‘lcs[i,j,k]’ или ‘mcs[i,j,k]’,
     соответственно.  Если аргумент равен ‘all’, тогда печатаются
     уникальные ненулевые значения как ‘lcs[i,j,k]’ и ‘mcs[i,j,k]’.
     Если аргумент равен ‘false’, то ни какие значения не отображаются.
     Массив ‘mcs[i,j,k]’ определен таким образом, что последний индекс
     является контравариантным.

 -- Функция: ricci (<dis>)
     Функция пакета ‘ctensor’, вычисляющая ковариантные (симметричные)
     компоненты тензора Риччи ‘ric[i,j]’.  Если аргумент <dis> равен
     ‘true’, то на экран выводится печать результатов вычисления
     ненулевых компонент тензора.

 -- Функция: uricci (<dis>)
     Эта функция сначала вычисляет ковариантные компоненты тензора Риччи
     ‘ric[i,j]’.  Затем с помощью контравариантной метрики вычисляется
     тензор Риччи со смешанными компонентами.  Если аргумент <dis> равен
     ‘true’, тогда смешанные компоненты ‘uric[i,j]’ (индекс ‘i’
     ковариантный, а индекс ‘j’ контравариантный), будут распечатаны.
     При ‘ricci(false)’ просто вычисляется массив ‘uric[i,j]’ без печати
     на экран.

 -- Функция: scurvature ()
     Возвращает значение скалярной кривизны, получаемое сверткой тензора
     кривизны Риччи.

 -- Функция: einstein (<dis>)
     Функция ‘einstein’ вычисляет смешанный тензор Эйнштейна после того
     как вычислены символы Кристоффеля и тензор Риччи пи помощи функций
     ‘christof’ и ‘ricci’.  Если аргумент <dis> равен ‘true’, тогда
     ненулевые компоненты тензора Эйнштейна ‘ein[i,j]’ будут напечатаны,
     где индекс ‘j’ является ковариантным.  Переключатель ‘rateinstein’
     вызывает рациональное упрощение результирующих компонент.  Если
     ‘ratfac’ равен ‘true’ тогда компоненты будут автоматически
     факторизованы.

 -- Функция: leinstein (<dis>)
     Вычисляет ковариантный тензор Эйнштейна.  ‘leinstein’ записывает
     компоненты ковариантного тензора Эйнштейна в массив ‘lein’.
     Контравариантные компоненты тензора Эйнштейна вычисляются исходя из
     смешанного тензора Эйнштейна ‘ein’.  Если аргумент <dis> равен
     ‘true’, тогда ненулевые компоненты ковариантного тензора Эйнштейна
     распечатываются на экране.

 -- Функция: riemann (<dis>)
     Функция ‘riemann’ вычисляет тензор кривизны Римана используя
     метрику и символы Кристоффеля.  При этом используются следующие
     соглашения:

                          l      _l       _l       _l   _m    _l   _m
           R[i,j,k,l] =  R    = |      - |      + |    |   - |    |
                          ijk     ij,k     ik,j     mk   ij    mj   ik

     Эти обозначения совместимы с используемыми в пакете ‘itensor’ и его
     функцией ‘icurvature’.  Если необязательный аргумент <dis> равен
     ‘true’, тогда ненулевые компоненты тензора ‘riem[i,j,k,l]’
     печатаются на экране.  Как и для тензора Эйнштейна, управление
     процессом упрощения компонент тензора Римана осуществляется при
     помощи различные переключателей(флагов).  Если ‘ratriemann’ равен
     ‘true’, тогда будет применено рациональное упрощение.  Если
     ‘ratfac’ равен ‘true’, тогда каждая компонента факторизуется.

     Если ‘cframe_flag’ равен ‘false’, тогда тензор Римана вычисляется
     непосредственно исходя из символов Кристоффеля.  Если ‘cframe_flag’
     равен ‘true’, тогда сначала вычисляется ковариантный тензор Римана
     исходя из компонент неголономного базиса.

 -- Функция: lriemann (<dis>)
     Ковариантный тензор Римана (‘lriem[]’).  Функция вычисляет
     ковариантный тензор Римана и заносит результаты в массив ‘lriem’.
     Если флаг <dis> равен ‘true’, то результаты вычислений уникальных
     ненулевых компонент тензора выводятся на экран.

     Если флаг ‘cframe_flag’ равен ‘true’, то ковариантный тензор Римана
     вычисляется напрямую по компонентам тетрады, если иначе, то вначале
     вычисляется тензор Римана ранга (3,1).

     Информация о порядке следования индексов подробнее освящена в
     пункте ‘riemann’.

 -- Функция: uriemann (<dis>)
     Вычисляет контравариантные компоненты тензора Римана и заносит их в
     матрицу ‘uriem[i,j,k,l]’.  Результаты вычислений печатаются на
     экране если флаг <dis> равен ‘true’.

 -- Функция: rinvariant ()
     Вычисляет инвариант Кречмана (Kretchmann) (‘kinvariant’), используя
     свертку тензоров.  Например,

          lriem[i,j,k,l]*uriem[i,j,k,l].

     Поскольку выражение может быть громоздким, то по умолчанию
     отключено автоматическое упрощение результата вычисления
     инварианта.

 -- Функция: weyl (<dis>)
     Вычисляет конформный тензор Вейля.  Если флаг <dis> равен ‘true’ -
     на экране печатаются не нулевые компоненты ‘weyl[i,j,k,l]’, если
     иначе, то результаты вычислений просто заносятся в матрицу.  Если
     ключ ‘ratweyl’ равен ‘true’, тогда производится автоматическое
     упрощение результата с использованием алгебры рациональных чисел;
     при ‘ratfac’ равном ‘true’ результат вычислений автоматически
     факторизуется.

26.2.3 Разложение в ряды Тейлора
--------------------------------

В пакете ‘ctensor’ реализованы возможности упрощения результатов
вычислений если метрика апроксимирована рядом Тейлора.  Для учета
метрики такого типа необходимо установить ключ ‘ctayswitch’ равным
‘true’.  Данный ключ заставляет использовать при пакетных вычислениях
функцию ‘ctaylor’ для упрощения результатов.

   Функция ‘ctaylor’ вызывается в следующих пакетных функциях ‘ctensor’:


         Функция      Комментарий
         ---------------------------------
         christof()   Только для mcs
         ricci()
         uricci()
         einstein()
         riemann()
         weyl()
         checkdiv()

 -- Функция: ctaylor ()

     Функция ‘ctaylor’ преобразует выражения заданных аргументов
     конвертируя их в Тейлоровские ряды, используя функцию ‘taylor’, и
     затем вызывая ‘ratdisrep’.  Это приводит к отбрасыванию слагаемых
     высокого порядка по переменной разложения ‘ctayvar’.  Порядок
     отбрасываемых членов определен переменной ‘ctaypov’; центральная
     точка окрестности разложения определяется переменной ‘ctaypt’.

     В качестве примера рассмотрим простую метрику , полученную в
     результате возмущений метрики Минковского.  Если не наложить
     ограничений, то даже диагональная метрика в этом случае приводит к
     достаточно громоздким выражениям тензора Эйнштейна:


          (%i1) load("ctensor");
          (%o1)       /share/tensor/ctensor.mac
          (%i2) ratfac:true;
          (%o2)                                true
          (%i3) derivabbrev:true;
          (%o3)                                true
          (%i4) ct_coords:[t,r,theta,phi];
          (%o4)                         [t, r, theta, phi]
          (%i5) lg:matrix([-1,0,0,0],[0,1,0,0],[0,0,r^2,0],
                          [0,0,0,r^2*sin(theta)^2]);
                                  [ - 1  0  0         0        ]
                                  [                            ]
                                  [  0   1  0         0        ]
                                  [                            ]
          (%o5)                   [          2                 ]
                                  [  0   0  r         0        ]
                                  [                            ]
                                  [              2    2        ]
                                  [  0   0  0   r  sin (theta) ]
          (%i6) h:matrix([h11,0,0,0],[0,h22,0,0],[0,0,h33,0],[0,0,0,h44]);
                                      [ h11   0    0    0  ]
                                      [                    ]
                                      [  0   h22   0    0  ]
          (%o6)                       [                    ]
                                      [  0    0   h33   0  ]
                                      [                    ]
                                      [  0    0    0   h44 ]
          (%i7) depends(l,r);
          (%o7)                               [l(r)]
          (%i8) lg:lg+l*h;
                [ h11 l - 1      0          0                 0            ]
                [                                                          ]
                [     0      h22 l + 1      0                 0            ]
                [                                                          ]
          (%o8) [                        2                                 ]
                [     0          0      r  + h33 l            0            ]
                [                                                          ]
                [                                    2    2                ]
                [     0          0          0       r  sin (theta) + h44 l ]
          (%i9) cmetric(false);
          (%o9)                                done
          (%i10) einstein(false);
          (%o10)                               done
          (%i11) ntermst(ein);
          [[1, 1], 62]
          [[1, 2], 0]
          [[1, 3], 0]
          [[1, 4], 0]
          [[2, 1], 0]
          [[2, 2], 24]
          [[2, 3], 0]
          [[2, 4], 0]
          [[3, 1], 0]
          [[3, 2], 0]
          [[3, 3], 46]
          [[3, 4], 0]
          [[4, 1], 0]
          [[4, 2], 0]
          [[4, 3], 0]
          [[4, 4], 46]
          (%o12)                               done

     Однако если считать что ‘l’ мало и оставить только линейные члены
     по ‘l’, тогда получим намного более простое выражение для тензора
     Эйнштейна:


          (%i14) ctayswitch:true;
          (%o14)                               true
          (%i15) ctayvar:l;
          (%o15)                                 l
          (%i16) ctaypov:1;
          (%o16)                                 1
          (%i17) ctaypt:0;
          (%o17)                                 0
          (%i18) christof(false);
          (%o18)                               done
          (%i19) ricci(false);
          (%o19)                               done
          (%i20) einstein(false);
          (%o20)                               done
          (%i21) ntermst(ein);
          [[1, 1], 6]
          [[1, 2], 0]
          [[1, 3], 0]
          [[1, 4], 0]
          [[2, 1], 0]
          [[2, 2], 13]
          [[2, 3], 2]
          [[2, 4], 0]
          [[3, 1], 0]
          [[3, 2], 2]
          [[3, 3], 9]
          [[3, 4], 0]
          [[4, 1], 0]
          [[4, 2], 0]
          [[4, 3], 0]
          [[4, 4], 9]
          (%o21)                               done
          (%i22) ratsimp(ein[1,1]);
                                   2      2  4               2     2
          (%o22) - (((h11 h22 - h11 ) (l )  r  - 2 h33 l    r ) sin (theta)
                                        r               r r

                                      2               2      4    2
                        - 2 h44 l    r  - h33 h44 (l ) )/(4 r  sin (theta))
                                 r r                r

     Данное приближение полезно в пределе слабого поля, вдали от
     гравитационных источников.

26.2.4 Неголономный базис
-------------------------

Если ключ ‘cframe_flag’ равен ‘true’, то пакетные вычисления выполняются
с использованием тетрадного (неголономного в общем случае) базиса.

 -- Функция: frame_bracket (<fr>, <fri>, <diagframe>)
     Скобка тетрады (‘fb[]’).

     Вычисляет скобку тетрады, следуя определению:

             c          c         c        d     e
          ifb   = ( ifri    - ifri    ) ifr   ifr
             ab         d,e       e,d      a     b

26.2.5 Алгебраическая классификация
-----------------------------------

Новой особенностью пакета ‘ctensor’ (начиная с ноября 2004) является
возможность вычисления классификации Петрова 4-мерного
пространственно-временного многообразия.  Демонстрационные вычисления по
данной теме представлены в файле ‘share/tensor/petrov.dem’.

 -- Функция: nptetrad ()
     Вычисляет световую тетраду (‘np’) Ньюмана-Пенроуза и связанную с
     ней дуальную часть (‘npi’), см.  ‘petrov’ для примера.

     Световая тетрада конструируется с использованием 4-х мерного
     ортонормального базиса метрики, обладающей сигнатурой (-,+,+,+).
     Компоненты световой тетрады связаны с обратной матрицей метрики
     следующими соотношениями:


          np  = (fri  + fri ) / sqrt(2)
            1       1      2

          np  = (fri  - fri ) / sqrt(2)
            2       1      2

          np  = (fri  + %i fri ) / sqrt(2)
            3       3         4

          np  = (fri  - %i fri ) / sqrt(2)
            4       3         4

 -- Функция: psi (<dis>)
     Вычисляет пять коэффициентов Ньюмана-Пенроуза ‘psi[0]’...‘psi[4]’.
     Если ‘psi’ равен ‘true’, эти коэффициенты печатаются на экране, см
     пример в пункте ‘petrov’.

     Коэффициенты вычисляются в координатном базисе из тензора Вейля.
     Если при использовании тетрадного базиса, компоненты тензора Вейля
     предварительно конвертируются в координатный базис.  Эта процедура
     не оптимальна с вычислительной точки зрения и поэтому перед
     вычислением тензора Вейля предварительно рекомендуется задать
     координатный базис.  Заметим однако, что вычисления световой
     тетрады (‘np’) Ньюмана-Пенроуза требует задания тетрадного базиса.
     Таким образом, имеющая смысл схема вычислений в этом случае может
     состоять из следующих этапов: вначале задается базис тетрады,
     который затем используется для вычисления метрики ‘lg’ (вычисляется
     автоматически при вызове ‘cmetric’) и обратной метрики ‘ug’; на
     этом этапе можно переключится обратно к координатному базису
     установив ключ ‘cframe_flag’ равным ‘false’ перед началом
     вычислений символов Кристоффеля.  Переход обратно к тетрадному
     базису на более поздних стадиях вычислений может привести к
     несогласованным результатам, поскольку в выражении перемешиваются
     результаты вычислений компонент тензоров выполненных в различных
     базисах.

 -- Функция: petrov ()
     Вычисляет классификацию Петрова для данной метрики, определяя
     ‘psi[0]’...‘psi[4]’.

     Например, нижеследующее показывает, как получить классификацию
     Петрова для метрики Керра:

          (%i1) load("ctensor");
          (%o1)       /share/tensor/ctensor.mac
          (%i2) (cframe_flag:true,gcd:spmod,ctrgsimp:true,ratfac:true);
          (%o2)                                true
          (%i3) ct_coordsys(exteriorschwarzschild,all);
          (%o3)                                done
          (%i4) ug:invert(lg)$
          (%i5) weyl(false);
          (%o5)                                done
          (%i6) nptetrad(true);
          (%t6) np =

          [ sqrt(r - 2 m)           sqrt(r)                                 ]
          [---------------   ---------------------    0            0        ]
          [sqrt(2) sqrt(r)   sqrt(2) sqrt(r - 2 m)                          ]
          [                                                                 ]
          [ sqrt(r - 2 m)            sqrt(r)                                ]
          [---------------  - ---------------------   0            0        ]
          [sqrt(2) sqrt(r)    sqrt(2) sqrt(r - 2 m)                         ]
          [                                                                 ]
          [                                          r      %i r sin(theta) ]
          [       0                    0          -------   --------------- ]
          [                                       sqrt(2)       sqrt(2)     ]
          [                                                                 ]
          [                                          r       %i r sin(theta)]
          [       0                    0          -------  - ---------------]
          [                                       sqrt(2)        sqrt(2)    ]

                                       sqrt(r)         sqrt(r - 2 m)
          (%t7) npi = matrix([- ---------------------,---------------, 0, 0],
                                sqrt(2) sqrt(r - 2 m) sqrt(2) sqrt(r)

                    sqrt(r)            sqrt(r - 2 m)
          [- ---------------------, - ---------------, 0, 0],
             sqrt(2) sqrt(r - 2 m)    sqrt(2) sqrt(r)

                     1               %i
          [0, 0, ---------, --------------------],
                 sqrt(2) r  sqrt(2) r sin(theta)

                     1                 %i
          [0, 0, ---------, - --------------------])
                 sqrt(2) r    sqrt(2) r sin(theta)

          (%o7)                                done
          (%i7) psi(true);
          (%t8)                              psi  = 0
                                                0

          (%t9)                              psi  = 0
                                                1

                                                    m
          (%t10)                             psi  = --
                                                2    3
                                                    r

          (%t11)                             psi  = 0
                                                3

          (%t12)                             psi  = 0
                                                4
          (%o12)                               done
          (%i12) petrov();
          (%o12)                                 D

     Вычисление классификации Петрова основано на алгоритме
     опубликованном в монографии "Classifying geometries in general
     relativity: III Classification in practice" by Pollney, Skea, and
     d’Inverno, Class.  Quant.  Grav.  17 2885-2902 (2000).  В текущем
     виде (по состоянию на 19 декабря 2004) код программы протестирован
     только для некоторых простых случаев и может содержать ошибки.

26.2.6 Кручение и неметричность
-------------------------------

В пакете ‘ctensor’ реализованы учета неметричности и кручения в
коэффициентах связности.

   Коэффициенты кручения вычисляются при помощи определенного
пользователем тензора кручения ранга (2,1) ‘tr’.  Используя его,
коэффициенты кручения, ‘kt’, вычисляются по формулам:


                   m          m      m
            - g  tr   - g   tr   - tr   g
               im  kj    jm   ki     ij  km
     kt   = -------------------------------
       ijk                 2


       k     km
     kt   = g   kt
       ij         ijm

   Заметим, что массив ‘kt’ содержит только смешанные компоненты.

   Коэффициенты неметричности вычисляются из предварительно
определенного пользователем вектора неметричности ‘nm’ по следующим
формулам:


                  k    k        km
            -nm  D  - D  nm  + g   nm  g
        k      i  j    i   j         m  ij
     nmc  = ------------------------------
        ij                2

   где D обозначает дельта-символ Кронекера.

   Если ключ ‘ctorsion_flag’ равен ‘true’, то коэффициенты ‘kt’
выделяются из смешанных компонент связности вычисляемых функцией
‘christof’ и запоминаются в массиве ‘mcs’.  Аналогичным образом Maxima
поступает, если флаг ‘cnonmet_flag’ равен ‘true’, в этом случае из
смешанных компонент связности выделяется массив ‘nmc’.

   Если необходимо, функция ‘christof’ вызывает функции ‘contortion’
‘nonmetricity’ для вычисления массивов ‘kt’ ‘nm’.

 -- Функция: contortion (<tr>)

     Вычисляет коэффициенты кручения ранга (2,1) из тензора кручения
     <tr>.

 -- Функция: nonmetricity (<nmс>)

     Вычисляет коэффициенты неметричности ранга (2,1) из вектора
     неметричности <nm>.

26.2.7 Вспомогательные средства
-------------------------------

 -- Функция: ctransform (<M>)
     Функция, выполняющая координатное преобразование произвольной
     симметричной матрицы <M>.  Пользователь интерактивно запрашивается
     системой о функциях осуществляющих преобразование (прошлое название
     ‘transform’).

 -- Функция: findde (<A>, <n>)

     возвращает список дифференциальных уравнений, соответствующих
     элементам <n> -ой квадратной матрицы <A>.  В текущем виде <n> может
     быть 2 или 3.  ‘deindex’ - список (определенный глобально)
     содержащий индексы матрицы <A> соответствующие этим
     дифференциальным уравнениям.  Для тензора Эйнштейна (‘ein’),
     представленного в форме двухмерного массива вычисленного по метрике
     данной ниже, функция ‘findde’ дает следующую систему уравнений:

          (%i1) load("ctensor");
          (%o1)       /share/tensor/ctensor.mac
          (%i2) derivabbrev:true;
          (%o2)                                true
          (%i3) dim:4;
          (%o3)                                  4
          (%i4) lg:matrix([a, 0, 0, 0], [ 0, x^2, 0, 0],
                                        [0, 0, x^2*sin(y)^2, 0], [0,0,0,-d]);
                                    [ a  0       0        0  ]
                                    [                        ]
                                    [     2                  ]
                                    [ 0  x       0        0  ]
          (%o4)                     [                        ]
                                    [         2    2         ]
                                    [ 0  0   x  sin (y)   0  ]
                                    [                        ]
                                    [ 0  0       0       - d ]
          (%i5) depends([a,d],x);
          (%o5)                            [a(x), d(x)]
          (%i6) ct_coords:[x,y,z,t];
          (%o6)                            [x, y, z, t]
          (%i7) cmetric();
          (%o7)                                done
          (%i8) einstein(false);
          (%o8)                                done
          (%i9) findde(ein,2);
                                                      2
          (%o9) [d  x - a d + d, 2 a d d    x - a (d )  x - a  d d  x
                  x                     x x         x        x    x

                                                        2          2
                                    + 2 a d d   - 2 a  d , a  x + a  - a]
                                             x       x      x
          (%i10) deindex;
          (%o10)                     [[1, 1], [2, 2], [4, 4]]

 -- Функция: cograd ()
     Вычисляет ковариантный градиент скалярной функции.  Пользователь
     может задать имя полученному вектору, согласно процедуре
     проиллюстрированной ниже в пункте ‘contragrad’.

 -- Функция: contragrad ()

     Вычисляет контравариантный градиент скалярной функции.
     Пользователь может задать имя полученному вектору, следуя примеру
     (вычисления используют метрику Шварцшильда):


          (%i1) load("ctensor");
          (%o1)       /share/tensor/ctensor.mac
          (%i2) derivabbrev:true;
          (%o2)                                true
          (%i3) ct_coordsys(exteriorschwarzschild,all);
          (%o3)                                done
          (%i4) depends(f,r);
          (%o4)                               [f(r)]
          (%i5) cograd(f,g1);
          (%o5)                                done
          (%i6) listarray(g1);
          (%o6)                            [0, f , 0, 0]
                                                r
          (%i7) contragrad(f,g2);
          (%o7)                                done
          (%i8) listarray(g2);
                                         f  r - 2 f  m
                                          r        r
          (%o8)                      [0, -------------, 0, 0]
                                               r

 -- Функция: dscalar ()
     вычисляет даламбертиан скалярной функции, (зависимость от
     переменных должна быть определена заранее), например:

          (%i1) load("ctensor");
          (%o1)       /share/tensor/ctensor.mac
          (%i2) derivabbrev:true;
          (%o2)                                true
          (%i3) ct_coordsys(exteriorschwarzschild,all);
          (%o3)                                done
          (%i4) depends(p,r);
          (%o4)                               [p(r)]
          (%i5) factor(dscalar(p));
                                    2
                              p    r  - 2 m p    r + 2 p  r - 2 m p
                               r r           r r        r          r
          (%o5)               --------------------------------------
                                                 2
                                                r

 -- Функция: checkdiv ()

     вычисляет ковариантную дивергенцию смешанного тензора второго ранга
     (первый индекс должен быть ковариантным).  На печать выводится
     n-соответствующих компонент полученного векторного поля, где n =
     ‘dim’.  Если аргументом функции является ‘g’ (метрический тензор),
     тогда для упрощения результата используется равенство нулю
     ковариантной дивергенции тензора Эйнштейна.  Результат вычислений
     (вектор) запоминается в массиве с именем ‘div’.

 -- Функция: cgeodesic (<dis>)
     Функция пакета ‘ctensor’ вычисляющая уравнения геодезических для
     заданной метрики.  Результат запоминается в массиве ‘geod[i]’.
     Если аргумент <dis> равен ‘true’, тогда на экране печатается
     результат вычислений.

 -- Функция: bdvac (<f>)

     генерирует ковариантные компоненты вакуумных уравнений поля теории
     Бранса-Дикке.  Скалярное поле определено аргументом <f>, который
     задается в виде взятого в кавычки имени функции вместе со своими
     функциональными аргументами, например, ‘bdvac('p(x))’.  Результат
     вычислений (компоненты поля ковариантного тензора 2-го ранга)
     запоминается в ‘bd’.

 -- Функция: invariant1 ()

     генерирует полевые уравнения Эйлера-Лагранжа для инвариантной
     плотности R^2.  Результат запоминается в массиве ‘inv1’.

 -- Функция: invariant2 ()

     *** ПОКА НЕ РЕАЛИЗОВАНО *** генерирует смешанные полевые уравнения
     Эйлера-Лагранжа для инвариантной плотности ‘ric[i,j]*uriem[i,j]’.
     Результат запоминается в массиве ‘inv2’.

 -- Функция: bimetric ()

     *** ПОКА НЕ РЕАЛИЗОВАНО *** генерирует полевые уравнения
     биметрической теории Розена.  Результат запоминается в массиве
     ‘rosen’.

26.2.8 Утилиты
--------------

 -- Функция: diagmatrixp (<M>)

     Возвращает ‘true’ если <M> - диагональная матрица (2-х мерный
     массив).

 -- Функция: symmetricp (<M>)

     Возвращает ‘true’ если <M> - симметричная матрица (2-х мерный
     массив).

 -- Функция: ntermst (<f>)
     Дает пользователю возможность оценить размеры массива компонент
     тензора <f>.  В результате печатается список двух элементов, где
     первый элемент является списком индексов компоненты тензора, а
     второй элемент соответствует количеству слагаемых этой компоненты.
     Таким способом можно быстро выявить ненулевые компоненты и оценить
     стратегию упрощения тензора.

 -- Функция: cdisplay (<ten>)
     показывает все элементы тензора <ten>, в виде многомерного массива.
     Тензора ранга 0 и 1, также как и другие типы переменных
     показываются стандартной функцией Maxima - ‘ldisplay’.  Тензоры
     ранга 2 печатаются в виде двухмерной матрицы, тензоры более
     высокого порядка выводятся на экран как список 2-мерных матриц.
     Например в следующем примере на экран выводится результаты
     вычисления тензора Римана для метрики Шварцшильда:

          (%i1) load("ctensor");
          (%o1)       /share/tensor/ctensor.mac
          (%i2) ratfac:true;
          (%o2)                                true
          (%i3) ct_coordsys(exteriorschwarzschild,all);
          (%o3)                                done
          (%i4) riemann(false);
          (%o4)                                done
          (%i5) cdisplay(riem);
                    [ 0               0                   0           0     ]
                    [                                                       ]
                    [                              2                        ]
                    [      3 m (r - 2 m)   m    2 m                         ]
                    [ 0  - ------------- + -- - ----      0           0     ]
                    [            4          3     4                         ]
                    [           r          r     r                          ]
                    [                                                       ]
          riem    = [                                m (r - 2 m)            ]
              1, 1  [ 0               0              -----------      0     ]
                    [                                     4                 ]
                    [                                    r                  ]
                    [                                                       ]
                    [                                           m (r - 2 m) ]
                    [ 0               0                   0     ----------- ]
                    [                                                4      ]
                    [                                               r       ]

                                          [    2 m (r - 2 m)       ]
                                          [ 0  -------------  0  0 ]
                                          [          4             ]
                                          [         r              ]
                               riem     = [                        ]
                                   1, 2   [ 0        0        0  0 ]
                                          [                        ]
                                          [ 0        0        0  0 ]
                                          [                        ]
                                          [ 0        0        0  0 ]

                                          [         m (r - 2 m)    ]
                                          [ 0  0  - -----------  0 ]
                                          [              4         ]
                                          [             r          ]
                               riem     = [                        ]
                                   1, 3   [ 0  0        0        0 ]
                                          [                        ]
                                          [ 0  0        0        0 ]
                                          [                        ]
                                          [ 0  0        0        0 ]

                                          [            m (r - 2 m) ]
                                          [ 0  0  0  - ----------- ]
                                          [                 4      ]
                                          [                r       ]
                               riem     = [                        ]
                                   1, 4   [ 0  0  0        0       ]
                                          [                        ]
                                          [ 0  0  0        0       ]
                                          [                        ]
                                          [ 0  0  0        0       ]

                                         [       0         0  0  0 ]
                                         [                         ]
                                         [       2 m               ]
                                         [ - ------------  0  0  0 ]
                              riem     = [    2                    ]
                                  2, 1   [   r  (r - 2 m)          ]
                                         [                         ]
                                         [       0         0  0  0 ]
                                         [                         ]
                                         [       0         0  0  0 ]

                       [     2 m                                         ]
                       [ ------------  0        0               0        ]
                       [  2                                              ]
                       [ r  (r - 2 m)                                    ]
                       [                                                 ]
                       [      0        0        0               0        ]
                       [                                                 ]
            riem     = [                         m                       ]
                2, 2   [      0        0  - ------------        0        ]
                       [                     2                           ]
                       [                    r  (r - 2 m)                 ]
                       [                                                 ]
                       [                                         m       ]
                       [      0        0        0         - ------------ ]
                       [                                     2           ]
                       [                                    r  (r - 2 m) ]

                                          [ 0  0       0        0 ]
                                          [                       ]
                                          [            m          ]
                                          [ 0  0  ------------  0 ]
                               riem     = [        2              ]
                                   2, 3   [       r  (r - 2 m)    ]
                                          [                       ]
                                          [ 0  0       0        0 ]
                                          [                       ]
                                          [ 0  0       0        0 ]

                                          [ 0  0  0       0       ]
                                          [                       ]
                                          [               m       ]
                                          [ 0  0  0  ------------ ]
                               riem     = [           2           ]
                                   2, 4   [          r  (r - 2 m) ]
                                          [                       ]
                                          [ 0  0  0       0       ]
                                          [                       ]
                                          [ 0  0  0       0       ]

                                                [ 0  0  0  0 ]
                                                [            ]
                                                [ 0  0  0  0 ]
                                                [            ]
                                     riem     = [ m          ]
                                         3, 1   [ -  0  0  0 ]
                                                [ r          ]
                                                [            ]
                                                [ 0  0  0  0 ]

                                                [ 0  0  0  0 ]
                                                [            ]
                                                [ 0  0  0  0 ]
                                                [            ]
                                     riem     = [    m       ]
                                         3, 2   [ 0  -  0  0 ]
                                                [    r       ]
                                                [            ]
                                                [ 0  0  0  0 ]

                                         [   m                      ]
                                         [ - -   0   0       0      ]
                                         [   r                      ]
                                         [                          ]
                                         [        m                 ]
                                         [  0   - -  0       0      ]
                              riem     = [        r                 ]
                                  3, 3   [                          ]
                                         [  0    0   0       0      ]
                                         [                          ]
                                         [              2 m - r     ]
                                         [  0    0   0  ------- + 1 ]
                                         [                 r        ]

                                              [ 0  0  0    0   ]
                                              [                ]
                                              [ 0  0  0    0   ]
                                              [                ]
                                   riem     = [            2 m ]
                                       3, 4   [ 0  0  0  - --- ]
                                              [             r  ]
                                              [                ]
                                              [ 0  0  0    0   ]

                                          [       0        0  0  0 ]
                                          [                        ]
                                          [       0        0  0  0 ]
                                          [                        ]
                               riem     = [       0        0  0  0 ]
                                   4, 1   [                        ]
                                          [      2                 ]
                                          [ m sin (theta)          ]
                                          [ -------------  0  0  0 ]
                                          [       r                ]

                                          [ 0        0        0  0 ]
                                          [                        ]
                                          [ 0        0        0  0 ]
                                          [                        ]
                               riem     = [ 0        0        0  0 ]
                                   4, 2   [                        ]
                                          [         2              ]
                                          [    m sin (theta)       ]
                                          [ 0  -------------  0  0 ]
                                          [          r             ]

                                        [ 0  0          0          0 ]
                                        [                            ]
                                        [ 0  0          0          0 ]
                                        [                            ]
                             riem     = [ 0  0          0          0 ]
                                 4, 3   [                            ]
                                        [                2           ]
                                        [         2 m sin (theta)    ]
                                        [ 0  0  - ---------------  0 ]
                                        [                r           ]

                     [        2                                             ]
                     [   m sin (theta)                                      ]
                     [ - -------------         0                0         0 ]
                     [         r                                            ]
                     [                                                      ]
                     [                         2                            ]
                     [                    m sin (theta)                     ]
          riem     = [        0         - -------------         0         0 ]
              4, 4   [                          r                           ]
                     [                                                      ]
                     [                                          2           ]
                     [                                   2 m sin (theta)    ]
                     [        0                0         ---------------  0 ]
                     [                                          r           ]
                     [                                                      ]
                     [        0                0                0         0 ]

          (%o5)                                done

 -- Функция: deleten (<L>, <n>)
     Возвращает новый список состоящий из элементов списка <L> с
     удаленным <n>-ым элементом.

26.2.9 Переменные пакета ctensor
--------------------------------

 -- Управляющая переменная: dim
     Значение по умолчанию: 4

     Опция пакета ‘ctensor’ (компонентные вычисления).  Размерность
     многообразия, по умолчанию: 4 Команда ‘dim: n’ переопределяет
     размерность величине равной ‘n’.

 -- Управляющая переменная: diagmetric
     Значение по умолчанию: ‘false’

     Опция пакета ‘ctensor’ (компонентные вычисления).  Если
     ‘diagmetric’ равен ‘true’, тогда вычисления всех геометрических
     объектов проводятся по упрощенной схеме: с учетом диагональности
     метрики.  Это позволяет уменьшить время счета.  Данная опция
     устанавливается автоматически если при вызове ‘csetup’ была задана
     диагональная метрика.

 -- Управляющая переменная: ctrgsimp

     Включает использование тригонометрических преобразований при
     упрощении тензора.  В настоящее время, ‘ctrgsimp’ влияет только на
     результаты вычислений, выполненные в тетрадном базисе.

 -- Управляющая переменная: cframe_flag

     Если ключ ‘cframe_flag’ равен ‘true’, тогда вычисления проводятся в
     тетрадном базисе (в общем случае с не голономной метрикой).  Базис
     определяется массивом дуального фрейма ‘fri’ и метрикой базиса
     ‘lfg’.  При вычислениях в декартовой тетраде массив, ‘lfg’ должен
     быть единичной матрицей соответствующего размера; при вычислениях с
     Лоренцевой тетрадой, массив ‘lfg’ должен иметь соответствующую
     сигнатуру.

 -- Управляющая переменная: ctorsion_flag

     Если ‘ctorsion_flag’ равен ‘true’, тогда при вычислении связности
     учитываются коэффициенты кручения ‘contortion’.  В свою очередь,
     коэффициенты кручения, ‘contortion’, вычисляются из заданного
     пользователем тензора кручения ‘tr’.

 -- Управляющая переменная: cnonmet_flag

     Если ‘cnonmet_flag’ равен ‘true’, тогда при вычислении связности
     учитывается неметричность ‘nonmetricity’, которая, сама по себе,
     вычисляется из заданного пользователем вектора неметричности ‘nm’.

 -- Управляющая переменная: ctayswitch

     Если ключ равен ‘true’, то при вычислениях используются ряды
     Тейлора.  В текущем состоянии пакета, эти ряды влияют на вычисление
     следующих тензоров: ‘christof’, ‘ricci’, ‘uricci’, ‘einstein’, и
     ‘weyl’.

 -- Управляющая переменная: ctayvar

     Переменная ряда Тейлора.  Она активируется при ‘ctayswitch’ равном
     ‘true’.

 -- Управляющая переменная: ctaypov

     Максимальная ряда Тэйлора.  Ее определение влияет на вычисления
     только если ‘ctayswitch’ равен ‘true’.

 -- Управляющая переменная: ctaypt

     Центральная точка ряда Тэйлора.  Ее определение влияет на
     вычисления только если ‘ctayswitch’ равен ‘true’.

 -- Системная переменная: gdet

     Детерминант метрического тензора ‘lg’.  Вычисляется функцией
     ‘cmetric’, когда флаг ‘cframe_flag’ равен ‘false’.

 -- Управляющая переменная: ratchristof

     Включает рациональное упрощение коэффициентов связности ‘christof’.

 -- Управляющая переменная: rateinstein
     Значение по умолчанию: ‘true’

     Если равен ‘true’ тогда проводится рациональное упрощение компонент
     тензора Эйнштейна; если ‘ratfac’ равен ‘true’, тогда компоненты
     тензора автоматически факторизуются.

 -- Управляющая переменная: ratriemann
     Значение по умолчанию: ‘true’

     Один из ключей, контролирующих упрощение тензора Римана; Если равен
     ‘true’ тогда применяется рациональное упрощение; если ‘ratfac’
     равен ‘true’, тогда компоненты тензора автоматически факторизуются.

 -- Управляющая переменная: ratweyl
     Значение по умолчанию: ‘true’

     Если равен ‘true’ тогда применяется рациональное упрощение тензора
     Вейля; если ‘ratfac’ равен ‘true’, тогда компоненты тензора
     автоматически факторизуются.

 -- Переменная: lfg
     Имя ковариантной метрики тетрады.  По умолчанию совпадает с
     Лоренцевой метрикой, имеет сигнатуру (+,+,+,-).  Используется когда
     ‘cframe_flag’ равен ‘true’.

 -- Переменная: ufg
     Имя контравариантной метрики тетрады.  Вычисляется из ‘lfg’, если
     вызывается функция ‘cmetric’ и флаг ‘cframe_flag’ равен ‘true’.

 -- Переменная: riem
     Тензор Римана ранга (3,1).  Вычисляется вызовом функции ‘riemann’.
     Для информации о порядке следования индексов см.  описание
     ‘riemann’.

     Если ‘cframe_flag’ равен ‘true’, ‘riem’ вычисляется по ковариантным
     компонентам тензора Римана ‘lriem’.

 -- Переменная: lriem

     Ковариантная версия тензора Римана.  Вычисляется вызовом функции
     ‘lriemann’.

 -- Переменная: uriem

     Контравариантная версия тензора Римана.  Вычисляется вызовом
     функции ‘uriemann’.

 -- Переменная: ric

     Смешанный тензор Риччи.  Вычисляется функцией ‘ricci’.

 -- Переменная: uric

     Контравариантный тензор Риччи.  Вычисляется функцией ‘uricci’.

 -- Переменная: lg

     Метрический тензор.  Данный тензор должен (наравне с переменной
     ‘dim’) определен до начала других вычислений.

 -- Переменная: ug

     Обратный метрический тензор.  Вычисляется функцией ‘cmetric’.

 -- Переменная: weyl

     Тензор Вейля.  Вычисляется функцией ‘weyl’.

 -- Переменная: fb

     Коммутатор (скобка) тетрады, вычисляется функцией ‘frame_bracket’.

 -- Переменная: kinvariant

     Инвариант Кретчмана.  Вычисляется функцией ‘rinvariant’.

 -- Переменная: np

     Нуль-тетрада Ньюмана-Пенроуза.  Вычисляется функцией ‘nptetrad’.

 -- Переменная: npi

     Нуль-тетрада Ньюмана-Пенроуза с поднятыми индексами; вычисляется
     процедурой ‘nptetrad’.  Определена посредством ‘ug.np’.
     Произведение ‘np.transpose(npi)’ является константой:

          (%i39) trigsimp(np.transpose(npi));
                                        [  0   - 1  0  0 ]
                                        [                ]
                                        [ - 1   0   0  0 ]
          (%o39)                        [                ]
                                        [  0    0   0  1 ]
                                        [                ]
                                        [  0    0   1  0 ]

 -- Переменная: tr

     Определенный пользователем тензор 3-го ранга, задающий кручение.
     Используется процедурой ‘contortion’.

 -- Переменная: kt

     Вклад кручения в коэффициенты связности, вычисляется из тензора
     кручения ‘tr’ функцией ‘contortion’.

 -- Переменная: nm

     Определенный пользователем вектор неметричности.  Используется
     функцией ‘nonmetricity’.

 -- Переменная: nmc

     Вклад неметричности в связность; вычисляется из ‘nm’ функцией
     ‘nonmetricity’.

 -- Системная переменная: tensorkill

     Переменная показывающая, что пакет ‘ctensor’ инициализирован.  Эти
     установки используются процедурой ‘csetup’, и переопределяются
     процедурой ‘init_ctensor’.

 -- Управляющая переменная: ct_coords
     Значение по умолчанию: ‘[]’

     Опция пакета ‘ctensor’ (компонентные вычисления тензоров).
     ‘ct_coords’ содержит список имен координат.  Обычно он определяется
     при вызове процедуры ‘csetup’.  Список может быть переопределен
     назначением нового списка ‘ct_coords: [j1, j2, ..., jn]’, j’s имена
     новых координат.  Смотри также ‘csetup’.

26.2.10 Зарезервированные имена
-------------------------------

Следующие имена используются функциями и процедурами пакета ‘ctensor’
(не следует их переопределять):

       Наименование Описание
       ----------------------------------------------------------------
       _lg()        Присваивается массиву lfg если используется
                    тетрадная метрика; по умолчанию присваивается
                    массиву lg
       _ug()        Присваивается массиву ufg если используется
                    тетрадная метрика; по умолчанию присваивается
                    массиву ug
       cleanup()    Удаляет элементы drom списка deindex
       contract4()  используется функцией psi()
       filemet()    используется функцией csetup() при чтении метрики
                    из файла
       findde1()    используется функцией findde()
       findde2()    используется функцией findde()
       findde3()    используется функцией findde()
       kdelt()      дельта-символ Кронекера (необобщенный)
       newmet()     используется функцией csetup() для интерактивного
                    определения метрики
       setflags()   используется функцией init_ctensor()
       readvalue()
       resimp()
       sermet()     используется функцией csetup() для ввода метрики
                    в виде разложения в ряд Тэйлора
       txyzsum()
       tmetric()    Метрика тетрады, используется функцией cmetric(),
                    если cframe_flag:true
       triemann()   Тензор Римана в тетрадном представлении,
                    используется если cframe_flag:true
       tricci()     Тензор Риччи в тетрадном представлении,
                    используется если cframe_flag:true
       trrc()       Коэффициенты вращения Риччи, используется
                    функцией christof()
       yesp()

26.2.11 Изменения
-----------------

В ноябре 2004 пакет ‘ctensor’ был существенно переписан.  Многие функции
и переменные были переименованы для того чтобы сделать данный пакет
совместимым с коммерческой версией Macsyma.

       Новое имя    Статое имя      Описание
       -----------------------------------------------------------------
       ctaylor()    DLGTAYLOR()     Разложение выражения в ряд
                                    Тэйлора
       lgeod[]      EM              Уравнения геодезических
       ein[]        G[]             Смешанный тензор Эйнштейна
       ric[]        LR[]            Смешанный тензор Риччи
       ricci()      LRICCICOM()     Вычисляет смешанный тензор Риччи
       ctaypov      MINP            Максимальная степень ряда Тэйлора
       cgeodesic()  MOTION          Вычисляет уравнения геодезических
       ct_coords    OMEGA           метрические координаты
       ctayvar      PARAM           Переменная ряда Тэйлора
       lriem[]      R[]
       uriemann()   RAISERIEMANN()  Вычисляет контравариантный тензор
                                    Римана
       ratriemann   RATRIEMAN       Рациональное упрощение тензора
                                    Римана
       uric[]       RICCI[]         Контравариантный тензор Риччи
       uricci()     RICCICOM()      Вычисляет контравариантный тензор
                                    Риччи
       cmetric()    SETMETRIC()     Определяет метрику
       ctaypt       TAYPT           Центральная точка окрестности ряда
                                    Тэйлора
       ctayswitch   TAYSWITCH       Ключ, устанавливающий использовать
                                    ли ряды Тэйлора в метрике
       csetup()     TSETUP()        Вызывает начало интерактивного
                                    режима задания метрики и пр.
       ctransform() TTRANSFORM()    Интерактивное преобразование
                                    координат
       uriem[]      UR[]            Контравариантный тензор Римана
       weyl[]       W[]             Тензор Вейля ранга (3,1)


File: maxima.info,  Node: Пакет atensor,  Next: Sums Products and Series,  Prev: Пакет ctensor,  Up: Top

27 Пакет atensor
****************

* Menu:

* Введение в пакет atensor::
* Функции и переменные пакета atensor::


File: maxima.info,  Node: Введение в пакет atensor,  Next: Функции и переменные пакета atensor,  Prev: Пакет atensor,  Up: Пакет atensor

27.1 Введение в пакет atensor
=============================

Пакет ‘atensor’ предназначен для вычислений с тензорными алгебрами.  Для
того, чтобы использовать ‘atensor’, надо ввести ‘load("atensor")’, с
последующим вызовом функции ‘init_atensor’.

   Основой пакета ‘atensor’ является набор правил упрощения для
оператора некоммутативного произведения ("‘.’" – dot product).
‘atensor’ знает несколько типов алгебр и соответствующий набор правил
активизируется при вызове функции ‘init_atensor’.

   Возможности пакета ‘atensor’ можно продемонстрировать определив
алгебру кватернионов как алгебру Клиффорда Cl(0,2) с двумя базисными
векторами.  В этом случае три кватернионные мнимые единицы
представляются двумя базисными векторами и их произведением:

         i = v     j = v     k = v  . v
              1         2         1    2

   Хотя ‘atensor’ имеет встроенное определение алгебры кватернионов, оно
не используется в данном примере, в котором мы построим таблицу
умножения кватернионов в виде матрицы:


     (%i1) load("atensor");
     (%o1)       /share/tensor/atensor.mac
     (%i2) init_atensor(clifford,0,0,2);
     (%o2)                                done
     (%i3) atensimp(v[1].v[1]);
     (%o3)                                 - 1
     (%i4) atensimp((v[1].v[2]).(v[1].v[2]));
     (%o4)                                 - 1
     (%i5) q:zeromatrix(4,4);
                                     [ 0  0  0  0 ]
                                     [            ]
                                     [ 0  0  0  0 ]
     (%o5)                           [            ]
                                     [ 0  0  0  0 ]
                                     [            ]
                                     [ 0  0  0  0 ]
     (%i6) q[1,1]:1;
     (%o6)                                  1
     (%i7) for i thru adim do q[1,i+1]:q[i+1,1]:v[i];
     (%o7)                                done
     (%i8) q[1,4]:q[4,1]:v[1].v[2];
     (%o8)                               v  . v
                                          1    2
     (%i9) for i from 2 thru 4 do for j from 2 thru 4 do
           q[i,j]:atensimp(q[i,1].q[1,j]);
     (%o9)                                done
     (%i10) q;
                        [    1        v         v      v  . v  ]
                        [              1         2      1    2 ]
                        [                                      ]
                        [   v         - 1     v  . v    - v    ]
                        [    1                 1    2      2   ]
     (%o10)             [                                      ]
                        [   v      - v  . v     - 1      v     ]
                        [    2        1    2              1    ]
                        [                                      ]
                        [ v  . v      v        - v       - 1   ]
                        [  1    2      2          1            ]

   В качестве базисных векторов ‘atensor’ использует переменные с
индексом.  Символ переменой хранится в ‘asymbol’ а индекс может
принимать значения от 1 до ‘adim’.  Для переменных с индексом
вычисляются билинейные формы ‘sf’, ‘af’ и ‘av’.  Вычисление подставляет
значение ‘aform[i,j]’ вместо ‘fun(v[i],v[j])’, где ‘v’ есть значение
‘asymbol’ и ‘fun’ есть ‘af’ или ‘sf’; либо подставляет ‘v[aform[i,j]]’
вместо ‘av(v[i],v[j])’.

   Функции ‘sf’, ‘af’ и ‘av’ могут быть переопределены пользователем.

   Когда пакет ‘atensor’ загружен, устанавливаются следующие значения
переключателей:

     dotscrules:true;
     dotdistrib:true;
     dotexptsimp:false;

   Если вы хотите поэкспериментировать с неассоциативными алгебрами надо
присвоить ‘dotassoc’ значение ‘false’.  Однако, в данном случае
‘atensimp’ не всегда может получить желаемое упрощение.


File: maxima.info,  Node: Функции и переменные пакета atensor,  Prev: Введение в пакет atensor,  Up: Пакет atensor

27.2 Функции и переменные пакета atensor
========================================

 -- Функция: init_atensor (<alg_type>, <opt_dims>)
 -- Функция: init_atensor (<alg_type>)

     Инициализирует пакет ‘atensor’ с указанием типа алгебры.  Здесь
     <alg_type> может принимать одно из следующих значений:

     ‘universal’: Универсальная алгебра без определенных правил
     коммутации.

     ‘grassmann’: Алгебра Грассмана, определяемая коммутационным
     правилом ‘u.v+v.u=0’.

     ‘clifford’: Алгебра Клиффорда, определяемая коммутационным правилом
     ‘u.v+v.u=-2*sf(u,v)’, где ‘sf’ есть симметричная скалярная функция.
     Для этой алгебры <opt_dims> может задавать до 3-х неотрицательных
     целых чисел, которые представляют собой число положительных,
     вырожденных и отрицательных размерностей алгебры.  Если <opt_dims>
     задано, то ‘atensor’ автоматически сконфигурирует значения ‘adim’ и
     ‘aform’.  В противном случае ‘adim’ принимает значение 0 а ‘aform’
     остается неопределенным.

     ‘symmetric’: Симметричная алгебра, определяемая коммутационным
     правилом ‘u.v-v.u=0’.

     ‘symplectic’: Симплектическая алгебра, определяемая коммутационным
     правилом ‘u.v-v.u=2*af(u,v)’, гда ‘af’ есть антисимметричная
     скалярная функция.  Для симплектической алгебры <opt_dims> может
     задавать до двух неотрицательных целых чисел, представляющих число
     невырожденных и вырожденных измерений соответственно.  Если
     <opt_dims> задано, то ‘atensor’ автоматически сконфигурирует
     значения ‘adim’ и ‘aform’.  В противном случае ‘adim’ принимает
     значение 0 а ‘aform’ остается неопределенным.

     ‘lie_envelop’: Обертывающая алгебра Ли, определяемая коммутационным
     правилом ‘u.v-v.u=2*av(u,v)’, где ‘av’ есть антисимметричная
     функция.

     ‘init_atensor’ также распознает несколько предопределенных типов
     алгебр:

     ‘complex’ реализует алгебру комплексных чисел, как алгебру
     Клиффорда Cl(0,1).  Вызов ‘init_atensor(complex)’ эквивалентен
     ‘init_atensor(clifford,0,0,1)’.

     ‘quaternion’ реализует алгебру кватернионов.  Вызов
     ‘init_atensor(quaternion)’ эквивалентен
     ‘init_atensor(clifford,0,0,2)’.

     ‘pauli’ реализует алгебру спиноров Паули как алгебру Клиффорда
     Cl(3,0).  Вызов ‘init_atensor(pauli)’ эквивалентен
     ‘init_atensor(clifford,3)’.

     ‘dirac’ реализует алгебру спиноров Дирака как алгебру Клиффорда
     Cl(3,1).  Вызов ‘init_atensor(dirac)’ эквивалентен
     ‘init_atensor(clifford,3,0,1)’.

 -- Функция: atensimp (<expr>)

     Упрощает алгебраическое выражение <expr> в соответствии с
     правилами, определенными при вызове ‘init_atensor’.  Упрощение
     сводится к рекурсивному применению коммутационных правил м
     вычислению, где возможно, значений ‘sf’, ‘af’ и ‘av’.  При этом
     применяются предосторожности, обеспечивающие то, что процесс
     упрощения завершится.

 -- Функция: alg_type

     Тип алгебры.  Допустимые значения: ‘universal’, ‘grassmann’,
     ‘clifford’, ‘symmetric’, ‘symplectic’ или ‘lie_envelop’.

 -- Переменная: adim
     Значение по умолчанию: 0

     Размерность алгебры.  ‘atensor’ использует ‘adim’ для того чтобы
     определить является ли индексированный объект допустимым базисным
     вектором.  См.  ‘abasep’.

 -- Переменная: aform
     Значение по умолчанию: ‘ident(3)’

     Значение билинейных форм ‘sf’, ‘af’ или ‘av’.  Значение по
     умолчанию – единичная 3х3 матрица ‘ident(3)’.

 -- Переменная: asymbol
     Значение по умолчанию: ‘v’

     Символ, используемый для обозначения базисного вектора.

 -- Функция: sf (<u>, <v>)

     Симметричная скалярная функция, используемая в коммутационных
     правилах.  По умолчанию с помощью ‘abasep’ проверяется, что оба
     аргумента функции являются базисными векторами, и если это так,
     подставляется соответствующее значение из матрицы ‘aform’.

 -- Функция: af (<u>, <v>)

     Антисимметричная скалярная функция, используемая в коммутационных
     правилах.  По умолчанию с помощью ‘abasep’ проверяется, что оба
     аргумента функции являются базисными векторами, и если это так,
     подставляется соответствующее значение из матрицы ‘aform’.

 -- Функция: av (<u>, <v>)

     Антисимметричная скалярная функция, используемая в коммутационных
     правилах.  По умолчанию с помощью ‘abasep’ проверяется, что оба
     аргумента функции являются базисными векторами, и если это так,
     подставляется соответствующее значение из матрицы ‘aform’.

     Например:

          (%i1) load("atensor");
          (%o1)       /share/tensor/atensor.mac
          (%i2) adim:3;
          (%o2)                                  3
          (%i3) aform:matrix([0,3,-2],[-3,0,1],[2,-1,0]);
                                         [  0    3   - 2 ]
                                         [               ]
          (%o3)                          [ - 3   0    1  ]
                                         [               ]
                                         [  2   - 1   0  ]
          (%i4) asymbol:x;
          (%o4)                                  x
          (%i5) av(x[1],x[2]);
          (%o5)                                 x
                                                 3

 -- Функция: abasep (<v>)

     Проверяет является ли аргумент базисным вектором для ‘atensor’.
     Т.е.  проверяет, что: это индексированная переменная, символ этой
     переменной совпадает с значением ‘asymbol’, индекс имеет числовое
     значение в пределах от 1 до ‘adim’.

