Тензоры: опыт создания пользовательского пакета программ
Отметим, что сама команда замены координат имеет вид
changeBas[<номер исходного базиса>,<номер целевого базиса>]
После ее успешного выполнения значения компонент тензоров возвращаются в целевом базисе. Если же выполнить замену не удалось, что бывает, если матрицы (функции) перехода не заданы и не могут быть вычислены внутри программы, то выдается сообщение, предлагающее задать необходимые матрицы (функции).
Дифференциальные формы: их разложение по базису, внешнее умножение и дифференцирование. В настоящий момент в пакете реализован ряд возможностей для работы с дифференциальными формами. Как уже упоминалось выше, можно задать кососимметрический тензор или тензорное поле типа (0,q) с помощью команд makeSkew, makeSkewTab или makeSkewField:
Дифференциальную форму можно разложить по базису. Дифференциальные формы также можно перемножить внешним образом (как описанные выше кососимметрические тензоры):
Можно задать форму с коэффициентами-функциями:
От такой формы можно взять внешний дифференциал, который, как и положено, будет дифференциальной формой:
Можно задать форму непосредственно, как вот такую форму P:
От нее тоже можно взять внешний дифференциал:
In[130]:=d[P]
однако ни P, ни d[P], в этом случае не являются тензорами:
In[131] := tensor [P] skew[P] tensor[d[P] ] tensorBas[P] skewBas[P] tensorBas[d[P]] skewBas[d[P]] Out[131] = False Out[132] = False Out[133] = False Out[134l = True Out[135] = True Out[136] = True Out[137] = True
Превратить их в тензорное поле можно так:
In[138]:=makeSkewTab[dP, toListSkew [d[P] ] ] tensor[dP] dP {1,2,3,4} Out[139] = True
Риманова метрика, риманова и аффинная связности. В пакете предусмотрена возможность объявить рассматриваемое многообразие (в текущей версии, напомним, многообразие состоит из одной карты) римановым. При этом задается или
- абстрактная метрика g и обратный тензор ig (команда makeRiemann ), или
- метрика с конкретной матрицей (команда makeRiemannTab[<матрица>] ).
В обоих случаях для метрики и обратного тензора зарезервированы символы g и ig :
In[141] := resetTensors ; makeBasisDif[{х, у}]; makeRiemann; Пакет Tensors перезапущен. Результаты вычислений аннулированы. Созданы метрические тензоры д типа (0,2) и ig типа (2,0) In[144] :=Row [ {val [g] //MatrixForm, val[ig] //MatrixForm} , Spacer[10]]
Отметим, что оба построенных тензора по определению симметричны. Аналогично:
In[145] := resetTensors ; makeBasisDif[{х, у}] ;
val[g] //MatrixForm Пакет Tensors перезапущен. Результаты вычислений аннулированы. Создан метрический тензор g типа (0,2) и обратный к нему тензор ig типа (2,0)
При этом, конечно, метрика - это тензор, компоненты которого пересчитывают при замене координат. Так, например, можно вычислить компоненты евклидовой метрики в полярных координатах:
Если задана метрика, то можно вычислить символы Кристоффеля соответствующей симметричной римановой связности, что делается с помощью команды makeCrRiemann . Для символов Кристоффеля зарезервирована буква ? (большая греческая буква гамма, Esc G Esc ). При этом с символами Кристоффеля во многом можно обращатьсякак с тензорами типа (1,2), а именно, можно посмотреть конкретную компоненту, можно вычислять их значение в текущих координатах с помощью все той же функции val :
In[151] := resetTensors ; makeBasisDif[{х, у, z}];
makeCrRiemann val[Г] Пакет Tensors перезапущен. Результаты вычислений аннулированы. Создан метрический тензор g типа (0,2) и обратный к нему тензор ig типа (2,0) Out[155]={{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}}
Мы вычислили символы Кристоффеля евклидовой связности, которые, разумеется, равны нулю. Пересчитаем их теперь, скажем, в цилиндрических координатах:
Или вот конкретная компонента:
Кроме того, предусмотрена возможность задавать абстрактную аффинную связность. При этом соответствующие функции
makeCrAffine[]
и
makeCrAffineTab[<таблица значений>>]
можно использовать как без явного указания имени связности (в этом случае ей присваивается имя Г), так и с указанием этого имени в виде последнего аргумента:
In[159] =makeCrAf f ine [ ] ; val[r]
In[161] :=makeCrAf fine [AA] ; val[AA]
Наконец, имеется возможность задавать метрику как тензорное поле. В этом случае компоненты метрики суть абстрактные функции от координат. Аналогичная возможность предусмотрена и для абстрактной аффинной связности. Соответствующие функции - это makeRiemannField , которая создает поля g и ig , makeCrAffineField[], которая создает связность Г , и makeCrAffineField[<имя связности>] , которая создает связность с заданным именем:
In[167] := resetTensors ; makeBasisDif[x, 2] ; makeRiemannField; makeCrRiemann;
Пакет Tensors перезапущен. Результаты вычислений аннулированы. Созданы метрические тензорные поля д типа (0,2) и ig типа (2,0)
Как работает пакет (краткое описание основных идей)
В этом разделе мы кратко опишем основные идеи и технические приемы, положенные в основу написания пакета. Сами тексты программ находятся в файле tensors.m. Этот файл тоже можно открыть в Mathematica (откройте). Возникнет специальным образом оформленное окно работы с пакетными файлами. Как и любой пакет, наш начинается оператором BeginPackage["Tensors'", {"Combinatorica'","GraphUtilities'"}], где первый аргумент - это имя пакета, а второй - список используемых пакетов, и заканчивается оператором EndPackage[].
В нашем пакете всего две клетки, первая состоит из команд вида <имя функции>::usage="текст описания.", служащих для описания пользовательских функций. Именно этот текст появляется на экране при выполнении команды ?<имя функции> . Если имеется несколько одноименных функций, то будут выведены все описания. Наконец, по команде ??<имя функции> на экран выводится весь код, задающий функцию:
In[172] := ? makeBasis
In[173] := ?? makeTensor
makeTensor [Т , р Integer, q Integer] : =
ConstantArray[nn[basis[curBas]], p + q] ; tensor[T] = True; type[T] = {p, q}; inBasis[T] = curBas; If[TrueQ[symm[T]], (symm[T]) = . ] ; If[TrueQ[skew[T] ] , (skew[T]) =.]; If[p=0&&q <= l, symm[T] = True; skew[T] = True] ;)
Полный список функций пакета можно увидеть, если кликнуть в кнопку Functions в окне работы с файлом пакета.