Maxima Manual: Функции и переменные пакета itensor

Previous: Введение в пакет itensor, Up: Пакет itensor [Contents][Index]

### 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`. Выполнение этой задачи займет некоторое время.

Previous: Введение в пакет itensor, Up: Пакет itensor [Contents][Index]