Update docs to match implementation of $build_and_dump_html_index
[maxima.git] / doc / info / es / Itensor.es.texi
blobc8ffa863037c9b6acae3c3d704368d5fcc9505bd
1 @c English version 2013-03-31
2 @menu
3 * Introducción a itensor::
4 * Funciones y variables para itensor::
5 @end menu
7 @node Introducción a itensor, Funciones y variables para itensor, itensor, itensor
8 @section Introducción a itensor
10 Maxima implementa dos tipos diferentes de manipulación simbólica de tensores: la manipulación de componentes
11 (paquete @code{ctensor}) y la manipulación indexada (paquete @code{itensor}).
13 Véase más abajo la nota sobre 'notación tensorial'.
15 La manipulación de componentes significa que los objetos geométricos tensoriales se representan como arreglos (arrays) o matrices. Operaciones tensoriales como la contracción o la diferenciación covariante se llevan a cabo sumando índices mudos con la sentencia @code{do}. Esto es, se realizan operaciones directamente con las componentes del tensor almacenadas en un arreglo o matriz.
17 La manipulación indexada de tensores se lleva a cabo mediante la representación de los tensores como funciones de sus índices covariantes, contravariantes y de derivadas. Operaciones tensoriales como la contracción o la diferenciación covariante se realizan manipulando directamente los índices, en lugar de sus componentes asociadas.
19 Estas dos técnicas para el tratamiento de los procesos diferenciales, algebraicos y analíticos en el contexto de la geometría riemanniana tienen varias ventajas y desventajas que surgen según la naturaleza y dificultad del problema que está abordando el usuario. Sin embargo, se deben tener presentes las siguientes características de estas dos técnicas:
21 La representación de los tensores y sus operaciones en términos de sus componentes facilita el uso de paquete @code{ctensor}. La especificación de la métrica y el cálculo de los tensores inducidos e invariantes es inmediato. Aunque toda la potencia de simplificación de Maxima se encuentra siempre a mano, una métrica compleja con dependencias funcionales y de coordenadas intrincada, puede conducir a expresiones de gran tamaño en las que la estructura interna quede oculta. Además, muchos cálculos requieren de expresiones intermedias que pueden provocar la detención súbita de los programas antes de que se termine el cálculo. Con la experiencia, el usuario podrá evitar muchas de estas dificultades.
23 Devido a la forma en que los tensores y sus operaciones se representan en términos de operaciones simbólicas con sus índices, expresiones que serían intratables en su representación por componentes pueden en ocasiones simplificarse notablemente utilizando las rutinas especiales para objetos simétricos del paquete @code{itensor}. De esta manera, la estructura de expresiones grandes puede hacerse más transparente. Por otro lado, debido a la forma especial de la representación indexada de tensores en @code{itensor}, en algunos casos el usuario encontrará dificultades con la especificación de la métrica o la definición de funciones.
25 El paquete @code{itensor} puede derivar respecto de una variable indexada, lo que 
26 permite utilizar el paquete cuando se haga uso del formalismo de lagrangiano y
27 hamiltoniano. Puesto que es posible derivar un campo lagrangiano respecto de
28 una variable de campo indexada, se puede hacer uso de Maxima para derivar las
29 ecuaciones de Euler-Lagrange correspondientes en forma indexada. Estas ecuaciones
30 pueden traducirse a componentes tensoriales (@code{ctensor}) con la función 
31 @code{ic_convert}, lo que permite resolver las ecuaciones de campo en cualquier
32 sistema de coordenadas, o obtener las ecuaciones de movimiento en forma 
33 hamiltoniana. Véanse dos ejemplos en @code{einhil.dem} y @code{bradic.dem}; 
34 el primero utiliza la acción de Einstein-Hilbert para derivar el campo
35 tensorial de Einstein en el caso homogéneo e isotrópico (ecuaciones de
36 Friedmann), así como en el caso esferosimétrico estático
37 (solución de Schwarzschild); el segundo demuestra cómo calcular las
38 ecuaciones de Friedmann a partir de la acción de la teoría
39 de la gravedad de Brans-Dicke, y también muestra cómo derivar el
40 hamiltoniano asociado con la teoría del campo escalar.
43 @subsection Notación tensorial
45 Hasta ahora, el paquete @code{itensor} de Maxima utilizaba una notación que algunas veces llevaba a una ordenación incorrecta de los índices. Por ejemplo:
47 @example
48 (%i2) imetric(g);
49 (%o2)                                done
50 (%i3) ishow(g([],[j,k])*g([],[i,l])*a([i,j],[]))$
51                                  i l  j k
52 (%t3)                           g    g    a
53                                            i j
54 (%i4) ishow(contract(%))$
55                                       k l
56 (%t4)                                a
57 @end example
59 Este resultado no es correcto a menos que @code{a} sea un tensor simétrico. La razón por la que esto ocurre es que aunque @code{itensor} mantenga correctamente el orden dentro del conjunto de índices covariantes y contravariantes, una vez un índice sea aumentado o disminuido, su posición relativa al otro conjunto de índices se pierde.
61 Para evitar este problema, se ha desarrollado una notación totalmente compatible con la anterior.En esta notación, los índices contravariantes se insertan en las posiciones correctas en la lista de índices covariantes, pero precedidos del signo negativo.
63 En esta notación, el ejemplo anterior da el resultado correcto:
65 @example
66 (%i5) ishow(g([-j,-k],[])*g([-i,-l],[])*a([i,j],[]))$
67                                  i l       j k
68 (%t5)                           g    a    g
69                                       i j
70 (%i6) ishow(contract(%))$
71                                       l k
72 (%t6)                                a
73 @end example
75 El único código que hace uso de esta notación es la función @code{lc2kdt}. @c FALTA TERMINAR ESTE PARRAFO (Mario)
77 Devido a que este código es nuevo, puede contener errores.
80 @subsection Manipulación indexada de tensores
82 El paquete @code{itensor} se carga haciendo @code{load("itensor")}. Para acceder a las demos se hará @code{demo(tensor)}.
84 En el paquete @code{itensor} un tensor se representa como un objeto indexado, esto es, como una función de tres grupos de índices: los covariantes, los contravariantes y los de derivadas. Los índices covariantes se especifican mediante una lista que será el primer argumento del objeto indexado, siendo los índices contravariantes otra lista que será el segundo argumento del mismo objeto indexado. Si al objeto indexado le falta cualquiera de estos grupos de índices, entonces se le asignará al argumento correspondiente la lista vacía @code{[]}.  Así, @code{g([a,b],[c])} representa un objeto indexado llamado @code{g}, el cual tiene dos índices covariantes @code{(a,b)}, un índice contravariante (@code{c}) y no tiene índices de derivadas.
86 Los índices de derivadas, si están presentes, se añaden como argumentos adicionales a la función simbólica que representa al tensor. Se pueden especificar explícitamente por el usuario o pueden crearse durante el proceso de diferenciación respecto de alguna coordenada. Puesto que la diferenciación ordinaria es conmutativa, los índices de derivadas se ordenan alfanuméricamente, a menos que la variable @code{iframe_flag} valga @code{true}, indicando que se está utilizando una métrica del sistema de referencia. Esta ordenación canónica hace posible que Maxima reconozca, por ejemplo, que @code{t([a],[b],i,j)} es lo mismo que @code{t([a],[b],j,i)}. La diferenciación de un objeto indexado con respecto de alguna coordenada cuyo índice no aparece como argumento de dicho objeto indexado, dará como resultado cero. Esto se debe a que Maxima no sabe si el tensor representado por el objeto indexado depende implícitamente de la coordenada correspondiente. Modificando la función @code{diff} de Maxima en @code{itensor}, se da por hecho que todos los objetos indexados dependen de cualquier variable de diferenciación, a menos que se indique lo contrario. Esto hace posible que la convención sobre la sumación se extienda a los índices de derivadas. El paquete @code{itensor} trata a los índices de derivadas como covariantes.
88 Las siguientes funciones forman parte del paquete @code{itensor} para la manipulación indexada de vectores. En lo que respecta a las rutinas de simplificación, no se considera en general que los objetos indexados tengan propiedades simétricas. Esto puede cambiarse reasignando a la variable @code{allsym[false]} el valor @code{true}, con lo cual los objetos indexados se considerarán simétricos tanto respecto de sus índices covariantes como contravariantes.
90 En general, el paquete @code{itensor} trata a los tensores como objetos opacos. Las ecuaciones tensoriales se manipulan en base a reglas algebraicas, como la simetría y la contracción. Además, en el paquete @code{itensor} hay funciones para la diferenciación covariante, la curvatura y la torsión. Los cálculos se pueden realizar respecto de una métrica del sistema de referencia móvil, dependiendo de las asignaciones dadas a la variable @code{iframe_flag}.
92 La siguiente sesión de ejemplo demuestra cómo cargar el paquete @code{itensor}, especificar el nombre de la métrica y realizar algunos cálculos sencillos.
94 @example
95 (%i1) load("itensor");
96 (%o1)      /share/tensor/itensor.lisp
97 (%i2) imetric(g);
98 (%o2)                                done
99 (%i3) components(g([i,j],[]),p([i,j],[])*e([],[]))$
100 (%i4) ishow(g([k,l],[]))$
101 (%t4)                               e p
102                                        k l
103 (%i5) ishow(diff(v([i],[]),t))$
104 (%t5)                                  0
105 (%i6) depends(v,t);
106 (%o6)                               [v(t)]
107 (%i7) ishow(diff(v([i],[]),t))$
108                                     d
109 (%t7)                               -- (v )
110                                     dt   i
111 (%i8) ishow(idiff(v([i],[]),j))$
112 (%t8)                                v
113                                       i,j
114 (%i9) ishow(extdiff(v([i],[]),j))$
115 (%t9)                             v    - v
116                                    j,i    i,j
117                                   -----------
118                                        2
119 (%i10) ishow(liediff(v,w([i],[])))$
120                                %3          %3
121 (%t10)                        v   w     + v   w
122                                    i,%3    ,i  %3
123 (%i11) ishow(covdiff(v([i],[]),j))$
124                                               %4
125 (%t11)                        v    - v   ichr2
126                                i,j    %4      i j
127 (%i12) ishow(ev(%,ichr2))$
128                 %4 %5
129 (%t12) v    - (g      v   (e p       + e   p     - e p       - e    p
130         i,j            %4     j %5,i    ,i  j %5      i j,%5    ,%5  i j
132                                          + e p       + e   p    ))/2
133                                               i %5,j    ,j  i %5
134 (%i13) iframe_flag:true;
135 (%o13)                               true
136 (%i14) ishow(covdiff(v([i],[]),j))$
137                                              %6
138 (%t14)                        v    - v   icc2
139                                i,j    %6     i j
140 (%i15) ishow(ev(%,icc2))$
141                                              %6
142 (%t15)                        v    - v   ifc2
143                                i,j    %6     i j
144 (%i16) ishow(radcan(ev(%,ifc2,ifc1)))$
145              %6 %7                    %6 %7
146 (%t16) - (ifg      v   ifb       + ifg      v   ifb       - 2 v
147                     %6    j %7 i             %6    i j %7      i,j
149                                              %6 %7
150                                         - ifg      v   ifb      )/2
151                                                     %6    %7 i j
152 (%i17) ishow(canform(s([i,j],[])-s([j,i])))$
153 (%t17)                            s    - s
154                                    i j    j i
155 (%i18) decsym(s,2,0,[sym(all)],[]);
156 (%o18)                               done
157 (%i19) ishow(canform(s([i,j],[])-s([j,i])))$
158 (%t19)                                 0
159 (%i20) ishow(canform(a([i,j],[])+a([j,i])))$
160 (%t20)                            a    + a
161                                    j i    i j
162 (%i21) decsym(a,2,0,[anti(all)],[]);
163 (%o21)                               done
164 (%i22) ishow(canform(a([i,j],[])+a([j,i])))$
165 (%t22)                                 0
166 @end example
169 @node Funciones y variables para itensor,  , Introducción a itensor, itensor
171 @section Funciones y variables para itensor
172 @subsection Trabajando con objetos indexados
175 @deffn {Función} dispcon (@var{tensor_1}, @var{tensor_2}, ...)
176 @deffnx {Función} dispcon (all)
178 Muestra las propiedades contractivas de sus argumentos tal como 
179 fueron asignadas por @code{defcon}. La llamada @code{dispcon (all)}
180 muestra todas propiedades contractivas que fueron definidas.
181 @end deffn
184 @deffn {Función} entertensor (@var{nombre})
186 Permite crear un objeto indexado llamado @var{nombre}, con cualquier número de índices tensoriales y de derivadas. Se admiten desde un único índice hasta una lista de índices. Véase el ejemplo en la descripción de @code{covdiff}.
188 @end deffn
190 @deffn {Función} changename (@var{anterior}, @var{nuevo}, @var{expr})
192 Cambia el nombre de todos los objetos indexados llamados @var{anterior} a @var{new} en @var{expr}. El argumento @var{anterior} puede ser un símbolo o una lista de la forma @code{[@var{nombre}, @var{m}, @var{n}]}, en cuyo caso sólo los objetos indexados de llamados @var{nombre} con @var{m} índices covariantes y @var{n} contravariantes se renombrarán como @var{nuevo}.
194 @end deffn
196 @deffn {Función} listoftens
198 Hace un listado de todos los tensores y sus índices en una expresión tensorial. Por ejemplo,
200 @example
202 (%i6) ishow(a([i,j],[k])*b([u],[],v)+c([x,y],[])*d([],[])*e)$
203                                          k
204 (%t6)                        d e c    + a    b
205                                   x y    i j  u,v
206 (%i7) ishow(listoftens(%))$
207                                k
208 (%t7)                        [a   , b   , c   , d]
209                                i j   u,v   x y
211 @end example
213 @end deffn
215 @deffn {Función} ishow (@var{expr})
217 Muestra @var{expr} con todos los objetos indexados que contiene, junto con los correspondientes índices covariantes (como subíndices) y contravariantes (como superíndices). Los índices de derivadas se muestran como subíndices, separados de los covariantes por una coma; véanse los múltiples ejemplos de este documento.
219 @end deffn
221 @deffn {Función} indices (@var{expr})
223 Devuelve una lista con dos elementos. El primer elemento es una lista con los índices libres, aquellos que aparecen una sola vez. El segundo elemento es una lista con los índices mudos en @var{expr}, aquellos que aparecen exactamente dos veces. Por ejemplo,
225 @example
227 (%i1) load("itensor");
228 (%o1)      /share/tensor/itensor.lisp
229 (%i2) ishow(a([i,j],[k,l],m,n)*b([k,o],[j,m,p],q,r))$
230                                 k l      j m p
231 (%t2)                          a        b
232                                 i j,m n  k o,q r
233 (%i3) indices(%);
234 (%o3)                 [[l, p, i, n, o, q, r], [k, j, m]]
236 @end example
238 Un producto tensorial que contenga el mismo índice más de dos veces es sintácticamente incorrecto. La función @code{indices} intenta tratar estas expresiones de una forma razonable; sin embargo, cuando se la obliga a manipular una expresión incorrecta puede tener un comportamiento imprevisto.
241 @end deffn
243 @deffn {Función} rename (@var{expr})
244 @deffnx {Función} rename (@var{expr}, @var{count})
246 Devuelve una expresión equivalente a @var{expr} pero con los índices mudos de cada término elegidos del conjunto  @code{[%1, %2,...]} si el segundo argumento opcional se omite. En otro caso, los índices mudos son indexados empezando con el valor @var{count}. Cada índice mudo en un producto será diferente. En el caso de las sumas, la función @code{rename} operará sobre cada término de la suma reinicializando el contador con cada término. De esta manera @code{rename} puede servir como simplificador tensorial. Además, los índices se ordenarán alfanuméricamente, si la variable @code{allsym} vale @code{true}, respecto de los índices covariantes y contravariantes dependiendo del valor de @code{flipflag}. Si  @code{flipflag} vale @code{false}, entonces los índices se renombrarán de acuerdo con el orden de los índices contravariantes. Si @code{flipflag} vale @code{true}, entonces los índices se renombrarán de acuerdo con el orden de los índices covariantes. Suele acontecer que el efecto combinado de los dos cambios de nombre reduzcan la expresión más de lo que que pueda reducir cualquiera de ellas por separado.
249 @example
251 (%i1) load("itensor");
252 (%o1)      /share/tensor/itensor.lisp
253 (%i2) allsym:true;
254 (%o2)                                true
255 (%i3) g([],[%4,%5])*g([],[%6,%7])*ichr2([%1,%4],[%3])*
256 ichr2([%2,%3],[u])*ichr2([%5,%6],[%1])*ichr2([%7,r],[%2])-
257 g([],[%4,%5])*g([],[%6,%7])*ichr2([%1,%2],[u])*
258 ichr2([%3,%5],[%1])*ichr2([%4,%6],[%3])*ichr2([%7,r],[%2]),noeval$
259 (%i4) expr:ishow(%)$
261        %4 %5  %6 %7      %3         u          %1         %2
262 (%t4) g      g      ichr2      ichr2      ichr2      ichr2
263                          %1 %4      %2 %3      %5 %6      %7 r
265         %4 %5  %6 %7      u          %1         %3         %2
266      - g      g      ichr2      ichr2      ichr2      ichr2
267                           %1 %2      %3 %5      %4 %6      %7 r
268 (%i5) flipflag:true;
269 (%o5)                                true
270 (%i6) ishow(rename(expr))$
271        %2 %5  %6 %7      %4         u          %1         %3
272 (%t6) g      g      ichr2      ichr2      ichr2      ichr2
273                          %1 %2      %3 %4      %5 %6      %7 r
275         %4 %5  %6 %7      u          %1         %3         %2
276      - g      g      ichr2      ichr2      ichr2      ichr2
277                           %1 %2      %3 %4      %5 %6      %7 r
278 (%i7) flipflag:false;
279 (%o7)                                false
280 (%i8) rename(%th(2));
281 (%o8)                                  0
282 (%i9) ishow(rename(expr))$
283        %1 %2  %3 %4      %5         %6         %7        u
284 (%t9) g      g      ichr2      ichr2      ichr2     ichr2
285                          %1 %6      %2 %3      %4 r      %5 %7
287         %1 %2  %3 %4      %6         %5         %7        u
288      - g      g      ichr2      ichr2      ichr2     ichr2
289                           %1 %3      %2 %6      %4 r      %5 %7
290 @end example
292 @end deffn
295 @deffn {Función} show (@var{expr})
296 Muestra @code{expr} con sus objetos indexados que tengan índices covariantes como subíndices y los contravariantes como superíndices.  Los índices derivados se muestran como subíndices, separados por una coma de los covariantes.
297 @end deffn
301 @defvr {Variable opcional} flipflag
302 Valor por defecto: @code{false}
304 Si vale @code{false} los índices se renombrarán de acuerdo con el orden de los índices covariantes, si @code{true} se renombrarán de acuerdo con el orden de los índices covariantes.
306 Si @code{flipflag} vale @code{false}, entonces @code{rename} construye una lista con los índices contravariantes según van apareciendo de izquierda a derecha; si vale @code{true}, entonces va formando la lista con los covariantes. Al primer índice mudo se le da el nombre @code{%1}, al siguiente @code{%2}, etc. Finalmente se hace la ordenación. Véase el ejemplo en la descripción de la función @code{rename}.
308 @end defvr
310 @deffn {Función} defcon (@var{tensor_1})
311 @deffnx {Función} defcon (@var{tensor_1}, @var{tensor_2}, @var{tensor_3})
313 Le asigna a gives @var{tensor_1} la propiedad de que la contracción de un producto de @var{tensor_1} por @var{tensor_2} da como resultado un @var{tensor_3} con los índices apropiados. Si sólo se aporta un argumento, @var{tensor_1}, entonces la contracción del producto de @var{tensor_1} por cualquier otro objeto indexado que tenga los índices apropiados, por ejemplo @code{my_tensor}, dará como resultado un objeto indexado con ese nombre, @code{my_tensor}, y con un nuevo conjunto de índices que reflejen las contracciones realizadas. Por ejemplo, si @code{imetric:g}, entonces @code{defcon(g)} implementará el aumento o disminución de los índices a través de la contracción con el tensor métrico. Se puede dar más de un @code{defcon} para el mismo objeto indexado, aplicándose el último. La variable 
314 @code{contractions} es una lista con aquellos objetos indexados a los que se le han dado propiedades de contracción con  @code{defcon}.
316 @end deffn
318 @deffn {Función} remcon (@var{tensor_1}, ..., @var{tensor_n})
319 @deffnx {Función} remcon (all)
321 Borra todas las propiedades de contracción de @var{tensor_1}, ..., @var{tensor_n}). La llamada @code{remcon(all)} borra todas las propiedades de contracción de todos los objetos indexados.
323 @end deffn
325 @deffn {Función} contract (@var{expr})
327 Lleva a cabo las contracciones tensoriales en @var{expr}, la cual puede ser cualquier combinación de sumas y productos. Esta función utiliza la información dada a la función @code{defcon}. Para obtener mejores resultados, @code{expr}
328 debería estar completamente expandida. La función @code{ratexpand} es la forma más rápida de expandir productos y potencias de sumas si no hay variables en los denominadores de los términos.
330 @end deffn
332 @deffn {Función} indexed_tensor (@var{tensor})
334 Debe ejecutarse antes de asignarle componentes a un @var{tensor} para el que ya existe un valor, como @code{ichr1}, @code{ichr2} o @code{icurvature}. Véase el ejemplo de la descripción de @code{icurvature}.
336 @end deffn
338 @deffn {Función} components (@var{tensor}, @var{expr})
340 Permite asignar un valor indexado a la expresión @var{expr} dando los valores de las componentes de @var{tensor}. El tensor debe ser de la forma @code{t([...],[...])}, donde cualquiera de las listas puede estar vacía. La expresión  @var{expr} puede ser cualquier objeto indexado que tenga otros objetos con los mismos índices libres que @var{tensor}. Cuando se utiliza para asignar valores al tensor métrico en el que las componentes contengan índices mudos, se debe tener cuidado en no generar índices mudos múltiples. Se pueden borrar estas asignaciones con la función  @code{remcomps}.
342 Es importante tener en cuenta que @code{components} controla la valencia del tensor, no el orden de los índices. Así, asignando componentes de la forma @code{x([i,-j],[])}, @code{x([-j,i],[])} o @code{x([i],[j])} todos ellos producen el mismo resultado, la asignación de componentes a un tensor de nombre @code{x} con valencia @code{(1,1)}.
344 Las componentes se pueden asignar a una expresión indexada de cuatro maneras, dos de las cuales implican el uso de la instrucción @code{components}:
346 1) Como una expresión indexada. Por ejemplo:
348 @example
350 (%i2) components(g([],[i,j]),e([],[i])*p([],[j]))$
351 (%i3) ishow(g([],[i,j]))$
352                                       i  j
353 (%t3)                                e  p
355 @end example
357 2) Como una matriz:
359 @example
360 (%i5) lg:-ident(4)$lg[1,1]:1$lg;
361                             [ 1   0    0    0  ]
362                             [                  ]
363                             [ 0  - 1   0    0  ]
364 (%o5)                       [                  ]
365                             [ 0   0   - 1   0  ]
366                             [                  ]
367                             [ 0   0    0   - 1 ]
369 (%i6) components(g([i,j],[]),lg);
370 (%o6)                                done
371 (%i7) ishow(g([i,j],[]))$
372 (%t7)                                g
373                                       i j
374 (%i8) g([1,1],[]);
375 (%o8)                                  1
376 (%i9) g([4,4],[]);
377 (%o9)                                 - 1
379 @end example
381 3) Como una función. Se puede utilizar una función de Maxima para especificar las componentes de un tensor en base a sus índices. Por ejemplo, el código siguiente asigna  @code{kdelta} a @code{h} si @code{h} tiene el mismo número de índices covariantes y contravariantes y no tiene índices de derivadas, asignándole @code{g} en otro caso:
383 @example
385 (%i4) h(l1,l2,[l3]):=if length(l1)=length(l2) and length(l3)=0
386   then kdelta(l1,l2) else apply(g,append([l1,l2], l3))$
387 (%i5) ishow(h([i],[j]))$
388                                           j
389 (%t5)                               kdelta
390                                           i
391 (%i6) ishow(h([i,j],[k],l))$
392                                      k
393 (%t6)                               g
394                                      i j,l
396 @end example
398 4) Utilizando los patrones de Maxima, en particular las funciones @code{defrule} y @code{applyb1}:
400 @example
402 (%i1) load("itensor");
403 (%o1)      /share/tensor/itensor.lisp
404 (%i2) matchdeclare(l1,listp);
405 (%o2)                                done
406 (%i3) defrule(r1,m(l1,[]),(i1:idummy(),
407       g([l1[1],l1[2]],[])*q([i1],[])*e([],[i1])))$
409 (%i4) defrule(r2,m([],l1),(i1:idummy(),
410       w([],[l1[1],l1[2]])*e([i1],[])*q([],[i1])))$
412 (%i5) ishow(m([i,n],[])*m([],[i,m]))$
413                                     i m
414 (%t5)                              m    m
415                                          i n
416 (%i6) ishow(rename(applyb1(%,r1,r2)))$
417                            %1  %2  %3 m
418 (%t6)                     e   q   w     q   e   g
419                                          %1  %2  %3 n
422 @end example
424 @end deffn
426 @deffn {Función} remcomps (@var{tensor})
428 Borra todos los valores de @var{tensor} que han sido asignados con la función @code{components}.
430 @end deffn
433 @deffn {Función} showcomps (@var{tensor})
435 Muestra las componentes de un tensor definidas con la instrucción @code{components}. Por ejemplo:
437 @example
439 (%i1) load("ctensor");
440 (%o1)       /share/tensor/ctensor.mac
441 (%i2) load("itensor");
442 (%o2)      /share/tensor/itensor.lisp
443 (%i3) lg:matrix([sqrt(r/(r-2*m)),0,0,0],[0,r,0,0],
444                 [0,0,sin(theta)*r,0],[0,0,0,sqrt((r-2*m)/r)]);
445                [         r                                     ]
446                [ sqrt(-------)  0       0              0       ]
447                [      r - 2 m                                  ]
448                [                                               ]
449                [       0        r       0              0       ]
450 (%o3)          [                                               ]
451                [       0        0  r sin(theta)        0       ]
452                [                                               ]
453                [                                      r - 2 m  ]
454                [       0        0       0        sqrt(-------) ]
455                [                                         r     ]
456 (%i4) components(g([i,j],[]),lg);
457 (%o4)                                done
458 (%i5) showcomps(g([i,j],[]));
459                   [         r                                     ]
460                   [ sqrt(-------)  0       0              0       ]
461                   [      r - 2 m                                  ]
462                   [                                               ]
463                   [       0        r       0              0       ]
464 (%t5)      g    = [                                               ]
465             i j   [       0        0  r sin(theta)        0       ]
466                   [                                               ]
467                   [                                      r - 2 m  ]
468                   [       0        0       0        sqrt(-------) ]
469                   [                                         r     ]
470 (%o5)                                false
472 @end example
474 La función @code{showcomps} también puede mostrar las componentes de tensores de rango mayor de 2.
476 @end deffn
478 @deffn {Función} idummy ()
480 Incrementa @code{icounter} y devuelve un índice de la forma @code{%n} siendo @code{n} un entero positivo.  Esto garantiza que índices mudos que sean necesarios para formar expresiones no entren en conflico con índices que ya están en uso. Véase el ejemplo de la descripción de @code{indices}.
482 @end deffn
484 @defvr {Variable opcional} idummyx
485 Valor por defecto: @code{%}
487 Es el prefijo de los índices mudos. Véase @code{indices}.
489 @end defvr
491 @defvr {Variable opcional} icounter
492 Valor por defecto: @code{1}
494 Determina el sufijo numérico a ser utilizado en la generación del siguiente índice mudo. El prefijo se determina con la opción @code{idummy} (por defecto: %).
495 @end defvr
497 @deffn {Función} kdelta (@var{L1}, @var{L2})
499 Es la función delta generalizada de Kronecker definida en el paquete @code{itensor} siendo @var{L1} la lista de índices covariantes y @var{L2} la lista de índices contravariantes. La función  @code{kdelta([i],[j])} devuelve el valor de la delta ordinaria de Kronecker. La instrucción @code{ev(@var{expr},kdelta)} provoca la evaluación de una expresión que contenga @code{kdelta([],[])}.
501 En un abuso de la notación, @code{itensor} también permite a @code{kdelta} tener 2 índices covariantes y ninguno contravariante, o 2 contravariantes y ninguno covariante. Esto es una funcionalidad del paquete, loque no implica que  @code{kdelta([i,j],[])} sea un objeto tensorial de pleno derecho.
503 @end deffn
505 @deffn {Función} kdels (@var{L1}, @var{L2})
507 Función delta de Kronecker simetrizada, utilizada en algunos cálculos. Por ejemplo:
509 @example
511 (%i1) load("itensor");
512 (%o1)      /share/tensor/itensor.lisp
513 (%i2) kdelta([1,2],[2,1]);
514 (%o2)                                 - 1
515 (%i3) kdels([1,2],[2,1]);
516 (%o3)                                  1
517 (%i4) ishow(kdelta([a,b],[c,d]))$
518                              c       d         d       c
519 (%t4)                  kdelta  kdelta  - kdelta  kdelta
520                              a       b         a       b
521 (%i4) ishow(kdels([a,b],[c,d]))$
522                              c       d         d       c
523 (%t4)                  kdelta  kdelta  + kdelta  kdelta
524                              a       b         a       b
526 @end example
528 @end deffn
530 @deffn {Función} levi_civita (@var{L})
532 Es el tensor de permutación de Levi-Civita, el cual devuelve 1  si la lista @var{L} con una permutación par de enteros, -1 si es en una permutación impar y 0 si algunos de los índices de @var{L} están repetidos.
534 @end deffn
536 @deffn {Función} lc2kdt (@var{expr})
538 Simplifica expresiones que contengan el símbolo de Levi-Civita, convirtiéndolas en expresiones con la delta de Kronecker siempre que sea posible. La diferencia principal entre esta función y la simple evaluación del símbolo de Levi-Civita consiste en que de esta última forma se obtienen expresiones de Kronecker con índices numéricos, lo que impide simplificaciones ulteriores. La función @code{lc2kdt} evita este problema, dando resultados con son más fáciles de simplificar con @code{rename} o @code{contract}.
540 @example
542 (%i1) load("itensor");
543 (%o1)      /share/tensor/itensor.lisp
544 (%i2) expr:ishow('levi_civita([],[i,j])
545                  *'levi_civita([k,l],[])*a([j],[k]))$
546                                   i j  k
547 (%t2)                  levi_civita    a  levi_civita
548                                        j            k l
549 (%i3) ishow(ev(expr,levi_civita))$
550                                   i j  k       1 2
551 (%t3)                       kdelta    a  kdelta
552                                   1 2  j       k l
553 (%i4) ishow(ev(%,kdelta))$
554              i       j         j       i   k
555 (%t4) (kdelta  kdelta  - kdelta  kdelta ) a
556              1       2         1       2   j
558                                1       2         2       1
559                         (kdelta  kdelta  - kdelta  kdelta )
560                                k       l         k       l
561 (%i5) ishow(lc2kdt(expr))$
562                      k       i       j    k       j       i
563 (%t5)               a  kdelta  kdelta  - a  kdelta  kdelta
564                      j       k       l    j       k       l
565 (%i6) ishow(contract(expand(%)))$
566                                  i           i
567 (%t6)                           a  - a kdelta
568                                  l           l
570 @end example
572 La función @code{lc2kdt} en ocasiones hace uso del tensor métrico. Si el tensor métrico no fue previamente definido con @code{imetric}, se obtiene un mensaje de error.
574 @example
576 (%i7) expr:ishow('levi_civita([],[i,j])
577                  *'levi_civita([],[k,l])*a([j,k],[]))$
578                                  i j            k l
579 (%t7)                 levi_civita    levi_civita    a
580                                                      j k
581 (%i8) ishow(lc2kdt(expr))$
582 Maxima encountered a Lisp error:
584  Error in $IMETRIC [or a callee]:
585  $IMETRIC [or a callee] requires less than two arguments.
587 Automatically continuing.
588 To reenable the Lisp debugger set *debugger-hook* to nil.
589 (%i9) imetric(g);
590 (%o9)                                done
591 (%i10) ishow(lc2kdt(expr))$
592          %3 i       k   %4 j       l     %3 i       l   %4 j
593 (%t10) (g     kdelta   g     kdelta   - g     kdelta   g    
594                     %3             %4               %3
595               k
596         kdelta  ) a
597               %4   j k
598 (%i11) ishow(contract(expand(%)))$
599                                   l i    l i  j
600 (%t11)                           a    - g    a
601                                               j
603 @end example
606 @end deffn
608 @c HMM, WHICH CATEGORY DOES THIS FALL INTO -- FUNCTION, VARIABLE, OTHER ??
609 @deffn {Función} lc_l
611 Regla de simplificación utilizada en expresiones que contienen el símbolo de @code{levi_civita} sin evaluar. Junto con  @code{lc_u}, puede utilizarse para simplificar muchas expresiones de forma más eficiente que la evaluación de @code{levi_civita}. Por ejemplo:
613 @example
615 (%i1) load("itensor");
616 (%o1)      /share/tensor/itensor.lisp
617 (%i2)  el1:ishow('levi_civita([i,j,k],[])*a([],[i])*a([],[j]))$
618                              i  j
619 (%t2)                       a  a  levi_civita
620                                              i j k
621 (%i3) el2:ishow('levi_civita([],[i,j,k])*a([i])*a([j]))$
622                                        i j k
623 (%t3)                       levi_civita      a  a
624                                               i  j
625 (%i4) canform(contract(expand(applyb1(el1,lc_l,lc_u))));
626 (%t4)                                  0
627 (%i5) canform(contract(expand(applyb1(el2,lc_l,lc_u))));
628 (%t5)                                  0
630 @end example
632 @end deffn
634 @c HMM, WHICH CATEGORY DOES THIS FALL INTO -- FUNCTION, VARIABLE, OTHER ??
635 @deffn {Función} lc_u
637 Regla de simplificación utilizada en expresiones que contienen el símbolo de @code{levi_civita} sin evaluar. Junto con  @code{lc_l}, puede utilizarse para simplificar muchas expresiones de forma más eficiente que la evaluación de @code{levi_civita}. Véase @code{lc_l}.
639 @end deffn
641 @deffn {Función} canten (@var{expr})
643 Simplifica @var{expr} renombrando (véase @code{rename}) y permutando índices mudos. La función @code{rename} se restringe a sumas de productos de tensores en los cuales no hay derivadas, por lo que está limitada y sólo debería utilizarse si @code{canform} no es capaz de de llevar a cabo la simplificación requerida.
645 La función @code{canten} devuelve un resultado matemáticamente correcto sólo si su argumento es una expresión completamente simétrica respecto de sus índices. Por esta razón, @code{canten} devuelve un error si @code{allsym} no vale @code{true}.
647 @end deffn
649 @deffn {Función} concan (@var{expr})
651 Similar a @code{canten} pero también realiza la contracción de los índices.
653 @end deffn
655 @subsection Simetrías de tensores
657 @defvr {Variable opcional} allsym
658 Valor por defecto: @code{false}
660 Si vale @code{true} entonces todos los objetos indexados se consideran simétricos respecto de todos sus índices covariantes y contravariantes. Si vale @code{false} entonces no se tienen en cuenta ningún tipo de simetría para estos índices. Los índices de derivadas se consideran siempre simétricos, a menos que la variable @code{iframe_flag} valga @code{true}.
662 @end defvr
664 @deffn {Función} decsym (@var{tensor}, @var{m}, @var{n}, [@var{cov_1}, @var{cov_2}, ...], [@var{contr_1}, @var{contr_2}, ...])
666 Declara propiedades de simetría para el @var{tensor} de @var{m} índices covariantes y @var{n} contravariantes. Los @var{cov_i} y @var{contr_i} son seudofunciones que expresan relaciones de simetría entre los índices covariantes y contravariantes, respectivamente. Éstos son de la forma @code{symoper(@var{index_1}, @var{index_2},...)} donde @code{symoper} es uno de @code{sym}, @code{anti} o @code{cyc} y los @var{index_i} son enteros que indican la posición del índice en el @var{tensor}.  Esto declarará a @var{tensor} simétrico, antisimétrico o cíclico respecto de @var{index_i}. La llamada @code{symoper(all)} indica que todos los índices cumplen la condición de simetría. Por ejemplo, dado un objeto @code{b} con 5 índices covariantes, @code{decsym(b,5,3,[sym(1,2),anti(3,4)],[cyc(all)])} declara @code{b} simétrico en el primer y segundo índices covariantes, antisimétrico en su tercer y cuarto índices también covariantes y cíclico en todos sus índices contravariantes. Cualquiera de las listas de declaración de simetrías puede ser nula. La función que realiza las simplificaciones es @code{canform}, como se ilustra en el siguiente ejemplo,
668 @example
670 (%i1) load("itensor");
671 (%o1)      /share/tensor/itensor.lisp
672 (%i2) expr:contract(expand(a([i1,j1,k1],[])
673             *kdels([i,j,k],[i1,j1,k1])))$
674 (%i3) ishow(expr)$
675 (%t3)         a      + a      + a      + a      + a      + a
676                k j i    k i j    j k i    j i k    i k j    i j k
677 (%i4) decsym(a,3,0,[sym(all)],[]);
678 (%o4)                                done
679 (%i5) ishow(canform(expr))$
680 (%t5)                              6 a
681                                       i j k
682 (%i6) remsym(a,3,0);
683 (%o6)                                done
684 (%i7) decsym(a,3,0,[anti(all)],[]);
685 (%o7)                                done
686 (%i8) ishow(canform(expr))$
687 (%t8)                                  0
688 (%i9) remsym(a,3,0);
689 (%o9)                                done
690 (%i10) decsym(a,3,0,[cyc(all)],[]);
691 (%o10)                               done
692 (%i11) ishow(canform(expr))$
693 (%t11)                        3 a      + 3 a
694                                  i k j      i j k
695 (%i12) dispsym(a,3,0);
696 (%o12)                     [[cyc, [[1, 2, 3]], []]]
698 @end example
701 @end deffn
703 @deffn {Función} remsym (@var{tensor}, @var{m}, @var{n})
705 Borra todas las propiedades de simetría del @var{tensor} que tiene @var{m} índices covariantes y @var{n} contravariantes.
706 @end deffn
708 @deffn {Función} canform (@var{expr})
709 @deffnx {Función} canform (@var{expr}, @var{rename})
711 Simplifica @var{expr} renombrando índices mudos y reordenando todos los índices según las condiciones de simetría que se le hayan impuesto. Si @code{allsym} vale @code{true} entonces todos los índices se consideran simétricos, en otro caso se utilizará la información sobre simetrías suministrada por @code{decsym}. Los índices mudos se renombran de la misma manera que en la función @code{rename}. Cuando @code{canform} se aplica a una expresión grande el cálculo puede llevar mucho tiempo. Este tiempo se puede acortar llamando primero  a @code{rename}.
712 Véase también el ejemplo de la descripción de @code{decsym}. La función @code{canform} puede que no reduzca completamente una expresión a su forma más sencilla, pero en todo caso devolverá un resultado matemáticamente correcto.
714 Si al parámetro opcional @var{rename} se le asigna el valor @code{false}, no se renombrarán los índices mudos.
715 @end deffn
717 @subsection Cálculo tensorial indexado
720 @deffn {Función} diff (@var{expr}, @var{v_1}, [@var{n_1}, [@var{v_2}, @var{n_2}] ...])
722 Se trata de la función de Maxima para la diferenciación, ampliada para las necesidades del paquete @code{itensor}. Calcula la derivada de @var{expr} respecto de @var{v_1} @var{n_1} veces, respecto de @var{v_2} @var{n_2} veces, etc. Para el paquete de tensores,la función ha sido modificada de manera que @var{v_i} puedan ser enteros desde 1 hasta el valor que tome la variable @code{dim}. Esto permite que la derivación se pueda realizar con respecto del @var{v_i}-ésimo miembro de la lista @code{vect_coords}. Si @code{vect_coords} guarda una variable atómica, entonces esa variable será la que se utilice en la derivación. Con esto se hace posible la utilización de una lista con nombres de coordenadas subindicadas, como @code{x[1]}, @code{x[2]}, ...
724 El paquete sobre tensores amplía las capacidades de @code{diff} con el
725 fin de poder calcular derivadas respecto de variables indexadas. En particular, es
726 posible derivar expresiones que contengan combinaciones del tensor métrico y
727 sus derivadas respecto del tensor métrico y su primera y segunda derivadas.
728 Estos métodos son particularmente útiles cuando se consideran los
729 formalismos lagrangianos de la teoría gravitatoria, permitiendo
730 obtener el tensor de Einstein y las ecuaciones de campo a partir del principio
731 de acción.
732 @end deffn
735 @deffn {Función} idiff (@var{expr}, @var{v_1}, [@var{n_1}, [@var{v_2}, @var{n_2}] ...])
736 Diferenciación inicial. Al contrario que @code{diff}, que deriva respecto de una variable independiente, @code{idiff} puede usarse para derivar respecto de una coordenada. @c FALTA COMPLETAR PARRAFO.
738 La función @code{idiff} también puede derivar el determinante del tensor métrico. Así, si @code{imetric} toma el valor @code{G} entonces @code{idiff(determinant(g),k)} devolverá @code{2*determinant(g)*ichr2([%i,k],[%i])} donde la índice mudo @code{%i} se escoge de forma apropiada.
739 @end deffn
741 @deffn {Función} liediff (@var{v}, @var{ten})
743 Calcula la derivada de Lie de la expresión tensorial @var{ten} respecto de campo vectorial @var{v}. La expresión @var{ten} debe ser cualquier tensor indexado; @var{v} debe ser el nombre (sin índices) de un campo vectorial. Por ejemplo:
745 @example
747 (%i1) load("itensor");
748 (%o1)      /share/tensor/itensor.lisp
749 (%i2) ishow(liediff(v,a([i,j],[])*b([],[k],l)))$
750        k    %2            %2          %2
751 (%t2) b   (v   a       + v   a     + v   a    )
752        ,l       i j,%2    ,j  i %2    ,i  %2 j
754                           %1  k        %1  k      %1  k
755                       + (v   b      - b   v    + v   b   ) a
756                               ,%1 l    ,l  ,%1    ,l  ,%1   i j
758 @end example
761 @end deffn
763 @deffn {Función} rediff (@var{ten})
765 Calcula todas las instrucciones @code{idiff} que aparezcan en la expresión tensorial @var{ten}.
767 @end deffn
769 @deffn {Función} undiff (@var{expr})
771 Devuelve una expresión equivalente a @var{expr} pero con todas las derivadas de los objetos indexados reemplazadas por la forma nominal de la función @code{idiff}. @c FALTA TERMINAR EL PARRAFO
773 @end deffn
776 @deffn {Función} evundiff (@var{expr})
778 Equivale a @code{undiff} seguido de  @code{ev} y @code{rediff}.
780 La razón de esta operación es evaluar de forma sencilla expresiones que no pueden ser directamente evaluadas en su forma derivada. Por ejemplo, lo siguiente provoca un error:
782 @example
783 (%i1) load("itensor");
784 (%o1)      /share/tensor/itensor.lisp
785 (%i2) icurvature([i,j,k],[l],m);
786 Maxima encountered a Lisp error:
788  Error in $ICURVATURE [or a callee]:
789  $ICURVATURE [or a callee] requires less than three arguments.
791 Automatically continuing.
792 To reenable the Lisp debugger set *debugger-hook* to nil.
793 @end example
795 Sin embargo, si @code{icurvature} se da en forma nominal, puede ser evaluada utilizando @code{evundiff}:
797 @example
798 (%i3) ishow('icurvature([i,j,k],[l],m))$
799                                          l
800 (%t3)                          icurvature
801                                          i j k,m
802 (%i4) ishow(evundiff(%))$
803              l              l         %1           l           %1
804 (%t4) - ichr2        - ichr2     ichr2      - ichr2       ichr2
805              i k,j m        %1 j      i k,m        %1 j,m      i k
807              l              l         %1           l           %1
808       + ichr2        + ichr2     ichr2      + ichr2       ichr2
809              i j,k m        %1 k      i j,m        %1 k,m      i j
810 @end example
812 Nota: en versiones antiguas de Maxima, las formas derivadas de los símbolos de
813 Christoffel no se podían evaluar. Este fallo ha sido subsanado, de manera que
814 @code{evundiff} ya no se necesita en expresiones como esta:
816 @example
817 (%i5) imetric(g);
818 (%o5)                                done
819 (%i6) ishow(ichr2([i,j],[k],l))$
820        k %3
821       g     (g         - g         + g        )
822               j %3,i l    i j,%3 l    i %3,j l
823 (%t6) -----------------------------------------
824                           2
826                          k %3
827                         g     (g       - g       + g      )
828                          ,l     j %3,i    i j,%3    i %3,j
829                       + -----------------------------------
830                                          2
831 @end example
835 @end deffn
837 @deffn {Función} flush (@var{expr}, @var{tensor_1}, @var{tensor_2}, ...)
839 Iguala a cero en la expresión @var{expr} todas las apariciones de @var{tensor_i} que no tengan índices de derivadas.
841 @end deffn
843 @deffn {Función} flushd (@var{expr}, @var{tensor_1}, @var{tensor_2}, ...)
845 Iguala a cero en la expresión @var{expr} todas las apariciones de @var{tensor_i} que tengan índices de derivadas
847 @end deffn
849 @deffn {Función} flushnd (@var{expr}, @var{tensor}, @var{n})
851 Iguala a cero en @var{expr} todas las apariciones del objeto diferenciado  @var{tensor} que tenga @var{n} o más
852 índices de derivadas, como demuestra el siguiente ejemplo:
854 @example
856 (%i1) load("itensor");
857 (%o1)      /share/tensor/itensor.lisp
858 (%i2) ishow(a([i],[J,r],k,r)+a([i],[j,r,s],k,r,s))$
859                                 J r      j r s
860 (%t2)                          a      + a
861                                 i,k r    i,k r s
862 (%i3) ishow(flushnd(%,a,3))$
863                                      J r
864 (%t3)                               a
865                                      i,k r
866 @end example
867 @end deffn
869 @deffn {Función} coord (@var{tensor_1}, @var{tensor_2}, ...)
871 Le da a @var{tensor_i} la propiedad de diferenciación coordenada, que la derivada del vector contravariante cuyo nombre es uno de los @var{tensor_i} es igual a la delta de Kronecker.  Por ejemplo, si se ha hecho @code{coord(x)} entonces  @code{idiff(x([],[i]),j)} da @code{kdelta([i],[j])}. La llamada @code{coord} devuelve una lista de todos los objetos indexados con esta propiedad.
873 @end deffn
875 @deffn {Función} remcoord (@var{tensor_1}, @var{tensor_2}, ...)
876 @deffnx {Función} remcoord (all)
878 Borra todas las propiedades de diferenciación coordenada de @code{tensor_i} que hayan sido establecidas por la función @code{coord}. La llamada @code{remcoord(all)} borra esta propiedad de todos los objetos indexados.
880 @end deffn
882 @deffn {Función} makebox (@var{expr})
883 Muestra @var{expr} de la misma manera que lo hace @code{show}; sin embargo, cualquier tensor de d'Alembert que aparezca en  @var{expr} estará indicado por @code{[]}.  Por ejemplo, @code{[]p([m],[n])} representa @code{g([],[i,j])*p([m],[n],i,j)}.
885 @end deffn
887 @deffn {Función} conmetderiv (@var{expr}, @var{tensor})
889 Simplifica expresiones que contengan derivadas ordinarias tanto de las formas covariantes como contravariantes del tensor métrico. Por ejemplo,  @code{conmetderiv} puede relacionar la derivada del tensor métrico contravariante con los símbolos de Christoffel, como se ve en el ejemplo:
891 @example
893 (%i1) load("itensor");
894 (%o1)      /share/tensor/itensor.lisp
895 (%i2) ishow(g([],[a,b],c))$
896                                       a b
897 (%t2)                                g
898                                       ,c
899 (%i3) ishow(conmetderiv(%,g))$
900                          %1 b      a       %1 a      b
901 (%t3)                 - g     ichr2     - g     ichr2
902                                    %1 c              %1 c
903 @end example
904 @end deffn
906 @deffn {Función} simpmetderiv (@var{expr})
907 @deffnx {Función} simpmetderiv (@var{expr}[, @var{stop}])
909 Simplifica expresiones que contienen productos de las derivadas del tensor métrico. La función @code{simpmetderiv} reconoce dos identidades:
911 @example
913    ab        ab           ab                 a
914   g   g   + g   g     = (g   g  )   = (kdelta )   = 0
915    ,d  bc        bc,d         bc ,d          c ,d
917 @end example
919 de donde 
921 @example
923    ab          ab
924   g   g   = - g   g
925    ,d  bc          bc,d
926 @end example
930 @example
932   ab          ab
933  g   g     = g   g
934   ,j  ab,i    ,i  ab,j
936 @end example
938 que se deduce de las simetrías de los símbolos de Christoffel.
940 La función @code{simpmetderiv} tiene un argumento opcional, el cual detiene la función después de la primera sustitución exitosa en un expresión producto. La función @code{simpmetderiv} también hace uso de la variable global @var{flipflag} que determina cómo aplicar una ordenación ``canónica'' a los índices de los productos.
942 Todo esto se puede utilizar para conseguir buenas simplificaciones que serían difíciles o imposibles de conseguir, lo que se demuestra en el siguiente ejemplo, que utiliza explícitamente las simplificaciones parciales de @code{simpmetderiv}:
944 @example
946 (%i1) load("itensor");
947 (%o1)      /share/tensor/itensor.lisp
948 (%i2) imetric(g);
949 (%o2)                                done
950 (%i3) ishow(g([],[a,b])*g([],[b,c])*g([a,b],[],d)*g([b,c],[],e))$
951                              a b  b c
952 (%t3)                       g    g    g      g
953                                        a b,d  b c,e
954 (%i4) ishow(canform(%))$
956 errexp1 has improper indices
957  -- an error.  Quitting.  To debug this try debugmode(true);
958 (%i5) ishow(simpmetderiv(%))$
959                              a b  b c
960 (%t5)                       g    g    g      g
961                                        a b,d  b c,e
962 (%i6) flipflag:not flipflag;
963 (%o6)                                true
964 (%i7) ishow(simpmetderiv(%th(2)))$
965                                a b  b c
966 (%t7)                         g    g    g    g
967                                ,d   ,e   a b  b c
968 (%i8) flipflag:not flipflag;
969 (%o8)                                false
970 (%i9) ishow(simpmetderiv(%th(2),stop))$
971                                a b  b c
972 (%t9)                       - g    g    g      g
973                                     ,e   a b,d  b c
974 (%i10) ishow(contract(%))$
975                                     b c
976 (%t10)                           - g    g
977                                     ,e   c b,d
979 @end example
981 Véase también @code{weyl.dem} para un ejemplo que utiliza @code{simpmetderiv} y @code{conmetderiv} para simplificar contracciones del tensor de Weyl.
983 @end deffn
985 @deffn {Función} flush1deriv (@var{expr}, @var{tensor})
987 Iguala a cero en @code{expr} todas las apariciones de @code{tensor} que tengan exactamente un índice derivado.
989 @end deffn
991 @subsection Tensores en espacios curvos
993 @deffn {Función} imetric (@var{g})
994 @deffnx {Variable de sistema} imetric
995 Especifica la métrica haciendo la asignación de la variable @code{imetric:@var{g}}, además las propiedades de contracción de la métrica @var{g} se fijan ejecutando las instrucciones @code{defcon(@var{g}), defcon(@var{g},@var{g},kdelta)}. La variable @code{imetric}, a la que no se le asigna ningún valor por defecto, tiene el valor de la métrica que se le haya asignado con la instrucción @code{imetric(@var{g})}.
997 @end deffn
999 @deffn {Función} idim (@var{n})
1000 Establece las dimensiones de la métrica. También inicializa las propiedades de antisimetría de los símbolos de Levi-Civita para la dimensión dada.
1002 @end deffn
1004 @deffn {Función} ichr1 ([@var{i}, @var{j}, @var{k}])
1005 Devuelve el símbolo de Christoffel de primera especie dado por la definición 
1006 @example
1007        (g      + g      - g     )/2 .
1008          ik,j     jk,i     ij,k
1009 @end example
1011 Para evaluar los símbolos de Christoffel de una métrica determinada, a la variable  @code{imetric} hay que asignarle un nombre como en el ejemplo de la descripción de @code{chr2}.
1013 @end deffn
1015 @deffn {Función} ichr2 ([@var{i}, @var{j}], [@var{k}])
1016 Devuelve el símbolo de Christoffel de segunda especie dado por la definición
1017 @example
1018                        ks
1019    ichr2([i,j],[k]) = g    (g      + g      - g     )/2
1020                              is,j     js,i     ij,s
1021 @end example
1022 @end deffn
1024 @deffn {Función} icurvature ([@var{i}, @var{j}, @var{k}], [@var{h}])
1025 Devuelve el tensor de curvatura de Riemann en términos de los símbolos de Christoffel de segunda especie (@code{ichr2}).  Se utiliza la siguiente notación:
1026 @example
1027                h             h            h         %1         h
1028      icurvature     = - ichr2      - ichr2     ichr2    + ichr2
1029                i j k         i k,j        %1 j      i k        i j,k
1030                                h          %1
1031                         + ichr2      ichr2
1032                                %1 k       i j
1033 @end example
1034 @end deffn
1036 @deffn {Función} covdiff (@var{expr}, @var{v_1}, @var{v_2}, ...)
1037 Devuelve la derivada covariante de @var{expr} respecto de las variables  @var{v_i} en términos de los símbolos de Christoffel de segunda especie (@code{ichr2}). Para evaluarlos debe hacerse @code{ev(@var{expr},ichr2)}.
1039 @example
1041 (%i1) load("itensor");
1042 (%o1)      /share/tensor/itensor.lisp
1043 (%i2) entertensor()$
1044 Enter tensor name: a;
1045 Enter a list of the covariant indices: [i,j];
1046 Enter a list of the contravariant indices: [k];
1047 Enter a list of the derivative indices: [];
1048                                       k
1049 (%t2)                                a
1050                                       i j
1051 (%i3) ishow(covdiff(%,s))$
1052              k         %1     k         %1     k
1053 (%t3)     - a     ichr2    - a     ichr2    + a
1054              i %1      j s    %1 j      i s    i j,s
1056              k     %1
1057       + ichr2     a
1058              %1 s  i j
1059 (%i4) imetric:g;
1060 (%o4)                                  g
1061 (%i5) ishow(ev(%th(2),ichr2))$
1062          %1 %4  k
1063         g      a     (g       - g       + g      )
1064                 i %1   s %4,j    j s,%4    j %4,s
1065 (%t5) - ------------------------------------------
1066                             2
1067     %1 %3  k
1068    g      a     (g       - g       + g      )
1069            %1 j   s %3,i    i s,%3    i %3,s
1070  - ------------------------------------------
1071                        2
1072     k %2  %1
1073    g     a    (g        - g        + g       )
1074           i j   s %2,%1    %1 s,%2    %1 %2,s     k
1075  + ------------------------------------------- + a
1076                         2                         i j,s
1078 @end example
1080 @end deffn
1082 @deffn {Función} lorentz_gauge (@var{expr})
1083 Impone la condición de Lorentz sustituyendo por 0 todos los objetos indexados de @var{expr} que tengan un índice derivado idéntico a un índice contravariante.
1085 @end deffn
1087 @deffn {Función} igeodesic_coords (@var{expr}, @var{nombre})
1089 Elimina los símbolos no diferenciados de Christoffel y las primeras derivadas del tensor métrico de @var{expr}. El argumento @var{nombre} de la función @code{igeodesic_coords} se refiere a la métrica @var{nombre} si aparece en @var{expr}, mientras que los coeficientes de conexión deben tener los nombres  @code{ichr1} y/o @code{ichr2}. El siguiente ejemplo hace la verificación de la identidad cíclica satisfecha por el tensor de curvatura de Riemann haciendo uso de la función @code{igeodesic_coords}.
1091 @example
1093 (%i1) load("itensor");
1094 (%o1)      /share/tensor/itensor.lisp
1095 (%i2) ishow(icurvature([r,s,t],[u]))$
1096              u            u         %1         u     
1097 (%t2) - ichr2      - ichr2     ichr2    + ichr2      
1098              r t,s        %1 s      r t        r s,t 
1100                                               u         %1
1101                                        + ichr2     ichr2
1102                                               %1 t      r s
1103 (%i3) ishow(igeodesic_coords(%,ichr2))$
1104                                  u            u
1105 (%t3)                       ichr2      - ichr2
1106                                  r s,t        r t,s
1107 (%i4) ishow(igeodesic_coords(icurvature([r,s,t],[u]),ichr2)+
1108             igeodesic_coords(icurvature([s,t,r],[u]),ichr2)+
1109             igeodesic_coords(icurvature([t,r,s],[u]),ichr2))$
1110              u            u            u            u
1111 (%t4) - ichr2      + ichr2      + ichr2      - ichr2
1112              t s,r        t r,s        s t,r        s r,t
1114                                              u            u
1115                                       - ichr2      + ichr2
1116                                              r t,s        r s,t
1117 (%i5) canform(%);
1118 (%o5)                                  0
1120 @end example
1122 @end deffn
1124 @subsection Sistemas de referencia móviles
1126 Maxima puede hacer cálculos utilizando sistemas de referencia móviles, los cuales pueden ser ortonormales o cualesquiera otros.
1128 Para utilizar sistemas de referencia, primero se debe asignar a la variable @code{iframe_flag} el valor @code{true}. Con esto se hace que los símbolos de Christoffel, @code{ichr1} y @code{ichr2}, sean reemplazados por los coeficientes @code{icc1} y @code{icc2} en los cálculos, cambiando así el comportamiento de @code{covdiff} y @code{icurvature}.
1130 El sistema de referencia se define con dos tensores: el campo del sistema de referencia inverso (@code{ifri}, la base dual tetrad) y la métrica del sistema de referencia @code{ifg}. La métrica del sistema de referencia es la matriz identidad en los sistemas de referencia ortonormales, o la métrica de Lorentz en sistemas de referencia ortonormales en el espacio-tiempo de Minkowski.  El campo del sistema de referencia inverso define la base del sistema de referencia con vectores unitarios. Las propiedades contractivas se definen para el campo y la métrica del sistema de referencia.
1132 Si @code{iframe_flag} vale @code{true}, muchas expresiones de @code{itensor} utilizan la métrica @code{ifg} en lugar de la métrica definida por @code{imetric} para incrementar y reducir índices.
1134 IMPORTANTE: Asignando a la variable @code{iframe_flag} el valor @code{true} NO deshace las propiedades contractivas de una métrica establecidas con una llamada a @code{defcon} o a @code{imetric}. Si se utiliza el campo del sistema de referencia, es mejor definir la métrica asignando su nombre a la variable  @code{imetric} y NO hacer una llamada a la función @code{imetric}.
1136 Maxima utiliza estos dos tensores para definir los coeficientes del sistema de referencia: @code{ifc1} y and @code{ifc2}, los cuales forman parte de los coeficientes de conexión @code{icc1} y @code{icc2}, tal como demuestra el siguiente ejemplo:
1138 @example
1140 (%i1) load("itensor");
1141 (%o1)      /share/tensor/itensor.lisp
1142 (%i2) iframe_flag:true;
1143 (%o2)                                true
1144 (%i3) ishow(covdiff(v([],[i]),j))$
1145                                i        i     %1
1146 (%t3)                         v   + icc2     v
1147                                ,j       %1 j
1148 (%i4) ishow(ev(%,icc2))$
1149                                %1     i       i
1150 (%t4)                         v   ifc2     + v
1151                                       %1 j    ,j
1152 (%i5) ishow(ev(%,ifc2))$
1153                           %1    i %2                i
1154 (%t5)                    v   ifg     ifc1        + v
1155                                          %1 j %2    ,j
1156 (%i6) ishow(ev(%,ifc1))$
1157             %1    i %2
1158            v   ifg     (ifb        - ifb        + ifb       )
1159                            j %2 %1      %2 %1 j      %1 j %2     i
1160 (%t6)      -------------------------------------------------- + v
1161                                    2                             ,j
1162 (%i7) ishow(ifb([a,b,c]))$
1163                                                    %3    %4
1164 (%t7)               (ifri        - ifri       ) ifr   ifr
1165                          a %3,%4       a %4,%3     b     c
1167 @end example
1169 Se utiliza un método alternativo  para calcular el sistema de referencia @code{ifb} si la variable @code{iframe_bracket_form} vale @code{false}:
1171 @example
1173 (%i8) block([iframe_bracket_form:false],ishow(ifb([a,b,c])))$
1174                                 %6    %5        %5      %6
1175 (%t8)              ifri     (ifr   ifr     - ifr     ifr  )
1176                        a %5     b     c,%6      b,%6    c
1178 @end example
1181 @defvr {Variable} ifb
1183 Es el sistema de referencia soporte. La contribución de la métrica del campo a los coeficientes de conexión se expresa utilizando:
1185 @example
1187           - ifb      + ifb      + ifb
1188                c a b      b c a      a b c
1189 ifc1    = --------------------------------
1190     abc                  2
1192 @end example
1194 El sistema de referencia soporte se define en términos del campo y la métrica del sistema de referencia. Se utilizan dos métodos alternativos dependiendo del valor de @code{frame_bracket_form}. Si vale @code{true} (que es el valor por defecto) o si @code{itorsion_flag} vale @code{true}:
1196 @example
1198           d      e                                      f
1199 ifb =  ifr    ifr   (ifri      - ifri      - ifri    itr   )
1200    abc    b      c       a d,e       a e,d       a f    d e
1203 @end example
1205 En otro caso:
1207 @example
1209              e      d        d      e
1210 ifb    = (ifr    ifr    - ifr    ifr   ) ifri
1211    abc       b      c,e      b,e    c        a d
1213 @end example
1216 @end defvr
1219 @defvr {Variable} icc1
1221 Coeficientes de conexión de primera especie. Se definen en @code{itensor} como
1223 @example
1225 icc1    = ichr1    - ikt1    - inmc1
1226     abc        abc       abc        abc
1228 @end example
1230 En esta expresión, si @code{iframe_flag} vale @code{true}, el símbolo de Christoffel @code{ichr1} se reemplaza por el coeficiente de conexión del sistema de referencia @code{ifc1}. Si @code{itorsion_flag} vale @code{false}, @code{ikt1} será omitido. También se omite si se utiliza una base, ya que la torsión ya está calculada como parte del sistema de referencia.
1232 @end defvr
1235 @defvr {Variable} icc2
1237 Coeficientes de conexión de segunda especie. Se definen en @code{itensor} como
1239 @example
1241     c         c        c         c
1242 icc2   = ichr2   - ikt2   - inmc2
1243     ab        ab       ab        ab
1245 @end example
1247 En esta expresión, si la variable @code{iframe_flag} vale @code{true}, el símbolo de Christoffel @code{ichr2} se reemplaza por el coeficiente de conexión del sistema de referencia @code{ifc2}. Si @code{itorsion_flag} vale @code{false}, @code{ikt2} se omite. También se omite si se utiliza una base de referncia. Por último, si  @code{inonmet_flag} vale @code{false}, se omite @code{inmc2}.
1249 @end defvr
1251 @defvr {Variable} ifc1
1253 Coeficiente del sistema de referencia de primera especie, también conocido como coeficientes de rotación de Ricci. Este tensor represnta la contribución de la métrica del sistema de referencia al coeficiente de conexión de primera especie, definido como
1255 @example
1257           - ifb      + ifb      + ifb
1258                c a b      b c a      a b c
1259 ifc1    = --------------------------------
1260     abc                   2
1263 @end example
1265 @end defvr
1267 @defvr {Variable} ifc2
1269 Coeficiente del sistema de referencia de segunda especie. Este tensor representa
1270 la contribución de la métrica del sistema de referencia al coeficiente 
1271 de conexión de segunda especie, definido como
1273 @example
1275     c       cd
1276 ifc2   = ifg   ifc1
1277     ab             abd
1279 @end example
1281 @end defvr
1283 @defvr {Variable} ifr
1285 El campo del sistema de referencia. Se contrae con el campo inverso @code{ifri} para formar la métrica del sistema de referencia, @code{ifg}.
1287 @end defvr
1289 @defvr {Variable} ifri
1291 Campo inverso del sistema de referencia. Especifica la base del sistema de referencia (vectores de la base dual).
1293 @end defvr
1295 @defvr {Variable} ifg
1297 La métrica del sistema de referencia. Su valor por defecto es @code{kdelta}, pero puede cambiarse utilizando 
1298 @code{components}.
1300 @end defvr
1302 @defvr {Variable} ifgi
1304 La métrica inversa del sistema de referencia. Se contrae con la métrica @code{ifg} para dar @code{kdelta}.
1306 @end defvr
1308 @defvr {Variable opcional} iframe_bracket_form
1309 Valor por defecto: @code{true}
1311 Especifica cómo se calcula @code{ifb}.
1313 @end defvr
1315 @subsection Torsión y no metricidad
1317 Maxima trabaja con conceptos como la torsión y la no metricidad. Cuando la variable @code{itorsion_flag} vale @code{true}, la contribución de la torsión se añade a los coeficientes de conexión. También se añaden las componentes de no metricidad cuando @code{inonmet_flag} vale  @code{true}.
1319 @defvr {Variable} inm
1321 Vector de no metricidad. La no metricidad conforme se define a partir de la derivada covariante del tensor métrico. La derivada covariante del tensor métrico, que normalmente es nula, se calcula, cuando @code{inonmet_flag} vale @code{true}, como 
1323 @example
1324 g     =- g  inm
1325  ij;k     ij   k
1326 @end example
1328 @end defvr
1331 @defvr {Variable} inmc1
1333 Permutación covariante de las componentes del vector de no metricidad. Se define como
1335 @example
1337            g   inm  - inm  g   - g   inm
1338             ab    c      a  bc    ac    b
1339 inmc1    = ------------------------------
1340      abc                 2
1342 @end example
1344 (Sustitúyase @code{g} por @code{ifg} si se utiliza una métrica para el sistema de referencia.)
1346 @end defvr
1348 @defvr {Variable} inmc2
1350 Permutación contravariante de las componentes del vector de no metricidad. Se utiliza en los coeficientes de conexión si @code{inonmet_flag} vale @code{true}. Se define como
1352 @example
1354                       c         c         cd
1355           -inm  kdelta  - kdelta  inm  + g   inm  g
1356      c        a       b         a    b          d  ab
1357 inmc2   = -------------------------------------------
1358      ab                        2
1360 @end example
1362 (Sustitúyase @code{g} por @code{ifg} si se utiliza una métrica para el sistema de referencia.)
1364 @end defvr
1366 @defvr {Variable} ikt1
1368 Permutación covariante del tensor de permutación, también conocido como contorsión. Se define como
1370 @example
1372                   d           d       d
1373           -g   itr  - g    itr   - itr   g
1374             ad    cb    bd    ca      ab  cd
1375 ikt1    = ----------------------------------
1376     abc                   2
1378 @end example
1380 (Sustitúyase @code{g} por @code{ifg} si se utiliza una métrica para el sistema de referencia.)
1382 @end defvr
1384 @defvr {Variable} ikt2
1386 Permutación contravariante del tensor de permutación, también conocido como contorsión. Se define como
1388 @example
1390     c     cd
1391 ikt2   = g   ikt1
1392     ab           abd
1394 @end example
1396 (Sustitúyase @code{g} por @code{ifg} si se utiliza una métrica para el sistema de referencia.)
1398 @end defvr
1400 @defvr {Variable} itr
1402 Tensor de torsión. Para una métrica con torsión, la diferenciación covariante iterada de una función escalar no conmuta, tal como demuestra el siguiente ejemplo:
1404 @example
1406 (%i1) load("itensor");
1407 (%o1)      /share/tensor/itensor.lisp
1408 (%i2) imetric:g;
1409 (%o2)                                  g
1410 (%i3) covdiff(covdiff(f([],[]),i),j)
1411          -covdiff(covdiff(f([],[]),j),i)$
1412 (%i4) ishow(%)$
1413                                    %4              %2
1414 (%t4)                    f    ichr2    - f    ichr2
1415                           ,%4      j i    ,%2      i j
1416 (%i5) canform(%);
1417 (%o5)                                  0
1418 (%i6) itorsion_flag:true;
1419 (%o6)                                true
1420 (%i7) covdiff(covdiff(f([],[]),i),j)
1421         -covdiff(covdiff(f([],[]),j),i)$
1422 (%i8) ishow(%)$
1423                            %8             %6
1424 (%t8)             f    icc2    - f    icc2    - f     + f
1425                    ,%8     j i    ,%6     i j    ,j i    ,i j
1426 (%i9) ishow(canform(%))$
1427                                    %1             %1
1428 (%t9)                     f    icc2    - f    icc2
1429                            ,%1     j i    ,%1     i j
1430 (%i10) ishow(canform(ev(%,icc2)))$
1431                                    %1             %1
1432 (%t10)                    f    ikt2    - f    ikt2
1433                            ,%1     i j    ,%1     j i
1434 (%i11) ishow(canform(ev(%,ikt2)))$
1435                       %2 %1                    %2 %1
1436 (%t11)          f    g      ikt1       - f    g      ikt1
1437                  ,%2            i j %1    ,%2            j i %1
1438 (%i12) ishow(factor(canform(rename(expand(ev(%,ikt1))))))$
1439                            %3 %2            %1       %1
1440                      f    g      g      (itr    - itr   )
1441                       ,%3         %2 %1     j i      i j
1442 (%t12)               ------------------------------------
1443                                       2
1444 (%i13) decsym(itr,2,1,[anti(all)],[]);
1445 (%o13)                               done
1446 (%i14) defcon(g,g,kdelta);
1447 (%o14)                               done
1448 (%i15) subst(g,nounify(g),%th(3))$
1449 (%i16) ishow(canform(contract(%)))$
1450                                            %1
1451 (%t16)                           - f    itr
1452                                     ,%1    i j
1454 @end example
1456 @end defvr
1458 @subsection Álgebra exterior
1460 Con el paquete @code{itensor} se pueden realizar operaciones en campos tensoriales covariantes antisimétricos. Un campo tensorial totalmente antisimétrrico de rango (0,L) se corresponde con una L-forma diferencial. Sobre estos objetos se define una operación que se llama producto exterior.
1462 Desafortunadamente no hay consenso entre los autores a la hora de definir el producto exterior. Algunos autores prefieren una definición que se corresponde con la noción de antisimetrización, con lo que el producto externo de dos campos vectoriales se definiría como
1464 @example
1465             a a  - a a
1466              i j    j i
1467  a  /\ a  = -----------
1468   i     j        2
1469 @end example
1471 De forma más general, el producto de una p-forma por una q-forma se definiría como
1473 @example
1474                        1     k1..kp l1..lq
1475 A       /\ B       = ------ D              A       B
1476  i1..ip     j1..jq   (p+q)!  i1..ip j1..jq  k1..kp  l1..lq
1477 @end example
1479 donde @code{D} es la delta de Kronecker.
1481 Otros autores, sin embargo, prefieren una definición ``geométrica'' que se corresponde con la noción del elemento de volumen,
1483 @example
1484 a  /\ a  = a a  - a a
1485  i     j    i j    j i
1486 @end example
1488 y, en el caso general,
1490 @example
1491                        1    k1..kp l1..lq
1492 A       /\ B       = ----- D              A       B
1493  i1..ip     j1..jq   p! q!  i1..ip j1..jq  k1..kp  l1..lq
1494 @end example
1496 Puesto que @code{itensor} un paquete de álgebra tensorial, la primera de estas dos definiciones parece la más natural. Sin embargo, muchas aplicaciones hacen uso de la segunda definición. Para resolver el dilema, se define una variable que controla el comportamiento del producto exteriort: si @code{igeowedge_flag} vale @code{false} (el valor por defecto), se utiliza la primera definición, si vale @code{true}, la segunda.
1498 @defvr {Operador} ~
1499 @ifinfo
1500 @fnindex Producto exterior
1501 @end ifinfo
1503 El operador del producto exterior se representa por el símbolo @code{~}. Este es un operador binario. Sus argumentos deben ser expresiones que tengan escalares, tensores covariantes de rango uno o tensores covariantes de rango @code{l} que hayan sido declarados antisimétricos en todos los índices covariantes.
1505 El comportamiento del operador del producto exterior se controla con la variable @code{igeowedge_flag}, como en el ejemplo siguiente:
1507 @example
1508 (%i1) load("itensor");
1509 (%o1)      /share/tensor/itensor.lisp
1510 (%i2) ishow(a([i])~b([j]))$
1511                                  a  b  - b  a
1512                                   i  j    i  j
1513 (%t2)                            -------------
1514                                        2
1515 (%i3) decsym(a,2,0,[anti(all)],[]);
1516 (%o3)                                done
1517 (%i4) ishow(a([i,j])~b([k]))$
1518                           a    b  + b  a    - a    b
1519                            i j  k    i  j k    i k  j
1520 (%t4)                     ---------------------------
1521                                        3
1522 (%i5) igeowedge_flag:true;
1523 (%o5)                                true
1524 (%i6) ishow(a([i])~b([j]))$
1525 (%t6)                            a  b  - b  a
1526                                   i  j    i  j
1527 (%i7) ishow(a([i,j])~b([k]))$
1528 (%t7)                     a    b  + b  a    - a    b
1529                            i j  k    i  j k    i k  j
1530 @end example
1532 @end defvr
1534 @defvr {Operador} |
1535 @ifinfo
1536 @fnindex Contracción con vector
1537 @end ifinfo
1539 La barra vertical @code{|} representa la operación "contracción con un vector". Cuando un tensor covariante totalmente antisimétrico se contrae con un vector contravariante, el resultado no depende del índice utilizado para la contracción. Así, es posible definir la operación de contracción de forma que no se haga referencia al índice.
1541 En el paquete @code{itensor} la contracción con un vector se realiza siempre respecto del primer índice de la ordenación literal. Ejemplo:
1543 @example
1544 (%i1) load("itensor");
1545 (%o1)      /share/tensor/itensor.lisp
1546 (%i2) decsym(a,2,0,[anti(all)],[]);
1547 (%o2)                                done
1548 (%i3) ishow(a([i,j],[])|v)$
1549                                     %1
1550 (%t3)                              v   a
1551                                         %1 j
1552 (%i4) ishow(a([j,i],[])|v)$
1553                                      %1
1554 (%t4)                             - v   a
1555                                          %1 j
1556 @end example
1558 Nótese que es primordial que los tensores utilizados junto con el operador @code{|} se declaren totalmente antisimétricos en sus  índices covariantes. De no ser así, se pueden obtener resultados incorrectos.
1560 @end defvr
1562 @deffn {Función} extdiff (@var{expr}, @var{i})
1564 Calcula la derivada exterior de @var{expr} con respecto del índice @var{i}. La derivada exterior se define formalmente como el producto exterior del operador de la derivada parcial y una forma diferencial. Por lo tanto, esta operación también se ve afectada por el valor que tome la variable @code{igeowedge_flag}. Ejemplo:
1566 @example
1567 (%i1) load("itensor");
1568 (%o1)      /share/tensor/itensor.lisp
1569 (%i2) ishow(extdiff(v([i]),j))$
1570                                   v    - v
1571                                    j,i    i,j
1572 (%t2)                             -----------
1573                                        2
1574 (%i3) decsym(a,2,0,[anti(all)],[]);
1575 (%o3)                                done
1576 (%i4) ishow(extdiff(a([i,j]),k))$
1577                            a      - a      + a
1578                             j k,i    i k,j    i j,k
1579 (%t4)                      ------------------------
1580                                       3
1581 (%i5) igeowedge_flag:true;
1582 (%o5)                                true
1583 (%i6) ishow(extdiff(v([i]),j))$
1584 (%t6)                             v    - v
1585                                    j,i    i,j
1586 (%i7) ishow(extdiff(a([i,j]),k))$
1587 (%t7)                    - (a      - a      + a     )
1588                              k j,i    k i,j    j i,k
1590 @end example
1592 @end deffn
1594 @deffn {Función} hodge (@var{expr})
1596 Calcula el dual de Hodge  @var{expr}. Por ejemplo:
1598 @example
1600 (%i1) load("itensor");
1601 (%o1)      /share/tensor/itensor.lisp
1602 (%i2) imetric(g);
1603 (%o2)                            done
1604 (%i3) idim(4);
1605 (%o3)                            done
1606 (%i4) icounter:100;
1607 (%o4)                             100
1608 (%i5) decsym(A,3,0,[anti(all)],[])$
1610 (%i6) ishow(A([i,j,k],[]))$
1611 (%t6)                           A
1612                                  i j k
1613 (%i7) ishow(canform(hodge(%)))$
1614                           %1 %2 %3 %4
1615                levi_civita            g        A
1616                                        %1 %102  %2 %3 %4
1617 (%t7)          -----------------------------------------
1618                                    6
1619 (%i8) ishow(canform(hodge(%)))$
1620                  %1 %2 %3 %8            %4 %5 %6 %7
1621 (%t8) levi_civita            levi_civita            g       
1622                                                      %1 %106
1623                              g        g        g      A         /6
1624                               %2 %107  %3 %108  %4 %8  %5 %6 %7
1625 (%i9) lc2kdt(%)$
1627 (%i10) %,kdelta$
1629 (%i11) ishow(canform(contract(expand(%))))$
1630 (%t11)                     - A
1631                               %106 %107 %108
1633 @end example
1635 @end deffn
1637 @defvr {Variable opcional} igeowedge_flag
1638 Valor por defecto: @code{false}
1640 Controla el comportamiento del producto exterior y de la derivada exterior. Cuando vale @code{false}, la noción de formas diferenciales se corresponde con el de campo tensorial covariante totalmente antisimétrico. Cuando vale @code{true}, las formas diferenciales se corresponden con la idea de elemento de volumen.
1642 @end defvr
1645 @subsection Exportando expresiones en TeX
1648 El paquete @code{itensor} dispone de soporte limitado para exportar expresiones con tensores a TeX. Puesto que las expresiones de @code{itensor} son llamadas a funciones, puede que la instrucción habitual en Maxima, @code{tex}, no devuleva los resultados esperados. Se puede utlizar el comando @code{tentex}, que tratará de traducir expresiones tensoriales a objetos de TeX correctamente indexados.
1650 @deffn {Función} tentex (@var{expr})
1652 Para utilizar la función @code{tentex}, primero se debe cargar @code{tentex}, tal como muestra el siguiente ejemplo:
1654 @example
1656 (%i1) load("itensor");
1657 (%o1)      /share/tensor/itensor.lisp
1658 (%i2) load("tentex");
1659 (%o2)       /share/tensor/tentex.lisp
1660 (%i3) idummyx:m;
1661 (%o3)                                  m
1662 (%i4) ishow(icurvature([j,k,l],[i]))$
1663             m1       i           m1       i           i
1664 (%t4)  ichr2    ichr2     - ichr2    ichr2     - ichr2
1665             j k      m1 l        j l      m1 k        j l,k
1667                                                       i
1668                                                + ichr2
1669                                                       j k,l
1670 (%i5) tentex(%)$
1671 $$\Gamma_@{j\,k@}^@{m_1@}\,\Gamma_@{l\,m_1@}^@{i@}-\Gamma_@{j\,l@}^@{m_1@}\,
1672  \Gamma_@{k\,m_1@}^@{i@}-\Gamma_@{j\,l,k@}^@{i@}+\Gamma_@{j\,k,l@}^@{i@}$$
1674 @end example
1676 Nótese la asignación de la variable @code{idummyx} para evitar la aparición del símbolo del porcentaje en la expresión en TeX, que puede dar errores de compilación.
1678 Téngase en cuenta que esta versión de la función @code{tentex} es experimental.
1680 @end deffn
1682 @subsection Interactuando con ctensor
1684 El paquete @code{itensor} genera código Maxima que luego puede ser ejecutado en el contexto del paquete @code{ctensor}. La función que se encarga de esta tarea es @code{ic_convert}.
1686 @deffn {Function} ic_convert (@var{eqn})
1688 Convierte la ecuación @var{eqn} del entorno @code{itensor} a una sentencia de asignación de @code{ctensor}. Sumas implícitas sobre índices mudos se hacen explícitas mientras que objetos indexados se transforman en arreglos (los subíndices de los arreglos se ordenan poniendo primero los covariantes seguidos de los contravariantes. La derivada de un objeto indexado se reemplazará por por la forma nominal de @code{diff} tomada con respecto a @code{ct_coords} con el subíndice correspondiente al índice derivado. Los símbolos de Christoffel @code{ichr1}  @code{ichr2} se traducen a @code{lcs} y @code{mcs}, respectivamente. Además, se añaden bucles @code{do} para la sumación de todos los índices libres, de manera que la sentencia traducida pueda ser evaluada haciendo simplemente @code{ev}. Los siguientes ejemplos muestran las funcionalidades de esta función.
1690 @example
1691 (%i1) load("itensor");
1692 (%o1)      /share/tensor/itensor.lisp
1693 (%i2) eqn:ishow(t([i,j],[k])=f([],[])*g([l,m],[])*a([],[m],j)
1694       *b([i],[l,k]))$
1695                              k        m   l k
1696 (%t2)                       t    = f a   b    g
1697                              i j      ,j  i    l m
1698 (%i3) ic_convert(eqn);
1699 (%o3) for i thru dim do (for j thru dim do (
1700        for k thru dim do
1701         t        : f sum(sum(diff(a , ct_coords ) b
1702          i, j, k                   m           j   i, l, k
1704  g    , l, 1, dim), m, 1, dim)))
1705   l, m
1706 (%i4) imetric(g);
1707 (%o4)                                done
1708 (%i5) metricconvert:true;
1709 (%o5)                                true
1710 (%i6) ic_convert(eqn);
1711 (%o6) for i thru dim do (for j thru dim do (
1712        for k thru dim do
1713         t        : f sum(sum(diff(a , ct_coords ) b
1714          i, j, k                   m           j   i, l, k
1716  lg    , l, 1, dim), m, 1, dim)))
1717    l, m
1718 @end example
1720 @end deffn
1722 @subsection Palabras reservadas
1724 Las siguientes palabras son utilizadas por el paquete @code{itensor} internamente, por lo que no deberían ser modificadas por el usuario:
1726 @c REFORMAT THIS TABLE USING TEXINFO MARKUP
1727 @example
1728   Palabra    Comentarios
1729   ------------------------------------------
1730   indices2() Versión interna de indices()
1731   conti      Lista los índices contravariantes
1732   covi       Lista los índices covariantes
1733   deri       Lista los índices de derivadas
1734   name       Devuelve el nombre de un objeto indexado
1735   concan
1736   irpmon
1737   lc0
1738   _lc2kdt0
1739   _lcprod
1740   _extlc
1741 @end example