~ubuntu-branches/ubuntu/karmic/maxima/karmic

« back to all changes in this revision

Viewing changes to share/tensor/ex_calc.mac

  • Committer: Bazaar Package Importer
  • Author(s): Camm Maguire
  • Date: 2004-11-13 18:39:14 UTC
  • mto: (2.1.2 hoary) (3.2.1 sid) (1.1.5 upstream)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20041113183914-ttig0evwuatnqosl
Tags: upstream-5.9.1
ImportĀ upstreamĀ versionĀ 5.9.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2003 Valerij Pipin <pip@iszf.irk.ru>
 
2
 *
 
3
 * This program is free software; you can redistribute it and/or
 
4
 * modify it under the terms of the GNU General Public License as
 
5
 * published by the Free Software Foundation; either version 2 of
 
6
 * the License, or (at your option) any later version.
 
7
 *
 
8
 * This program is distributed in the hope that it will be
 
9
 * useful, but WITHOUT ANY WARRANTY; without even the implied
 
10
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 
11
 * PURPOSE.  See the GNU General Public License for more details.
 
12
 *
 
13
 * Commentary:
 
14
 * Its purpose is to extend the maxima's itensor ability to manage the
 
15
 exterior forms. We introduce the "&" operator for the exterior product,
 
16
 the "|_" for the inner product of a form with a vector and "@L" for the
 
17
 Lie derivative of the form. 
 
18
*/
 
19
load("tensor/itensor")$
 
20
infix("&");
 
21
declare("&",additive); 
 
22
 
 
23
"&"(ANY,BODY):=block(local(I),
 
24
  L1:first(indices(ANY)),
 
25
  L2:first(indices(BODY)),
 
26
  if L1=[] then return(ANY*BODY)
 
27
  else if L2=[] then return(ANY*BODY)
 
28
  else ( L11 : MAKELIST(DUMMY(), I,1, LENGTH(L1)),
 
29
    L22 : MAKELIST(DUMMY(), I,1, LENGTH(L2)),
 
30
    L1S:MAP("=",L1,L11), L2S:MAP("=",L2,L22),
 
31
    LK1:append(L1,L2),LK2:append(L11,L22),
 
32
    ANY:sublis(L1S,ANY), BODY:sublis(L2S,BODY),
 
33
    evf:(if evenp(length(LK1)) then 1 else -1),
 
34
    canform(contract(
 
35
        expand(evf*KDELTA(LK1,LK2)*ANY*BODY/(length(LK1)-1)!)))));
 
36
 
 
37
infix("@");
 
38
declare("@",additive);
 
39
"@"(forma,ind):=block(L1:first(indices(forma)),
 
40
  if L1=[] then return(diff(forma,ind))
 
41
  else ( L11 : MAKELIST(DUMMY(), I,1, LENGTH(L1)),
 
42
    L1S:MAP("=",L1,L11),
 
43
    LK1:append([ind],L1),
 
44
    indd:dummy(),LK2:append(L11,[indd]),
 
45
    forma:sublis(L1S,forma),
 
46
    evf:(if evenp(length(LK1)) then 1 else -1),
 
47
    contract(canform(ratexpand(
 
48
          evf*kdelta(LK1,LK2)*diff(forma,indd)/(length(LK1)-1)!)))));
 
49
 
 
50
/* VTT: To ensure consistent application of the "first" index in |_ */
 
51
PERMUTATOR(L):=BLOCK([RESULT:1,TEMP],
 
52
        FOR I THRU LENGTH(L)-1 DO IF ORDERLESSP(L[I+1],L[I]) THEN
 
53
        (TEMP:L[I+1],L[I+1]:L[I],L[I]:TEMP,I:0,RESULT:-RESULT),
 
54
        [RESULT,L]
 
55
);
 
56
 
 
57
infix("|_");
 
58
declare("|_",additive);
 
59
/* VTT: ADDITIVE doesn't always do the trick so we break up sums manually */
 
60
"|_"(forma,vec):=BLOCK(LOCAL(ind,perm),
 
61
  IF NOT(ATOM(forma)) AND (OP(forma)="+" OR OP(forma)="=") THEN
 
62
    APPLY(OP(forma),[PART(forma,1)|_vec,REST(forma)|_vec])
 
63
  ELSE (perm:PERMUTATOR(first(indices(forma))),
 
64
    IF perm[2]=[] THEN 0
 
65
    ELSE perm[1]*(CONTRACT(CANFORM(EXPAND(forma*vec([],[FIRST(perm[2])])))))));
 
66
 
 
67
infix("@L");
 
68
 
 
69
declare("@L",additive);
 
70
 
 
71
"@L"(forma,L1):=block(local(temp1,temp2,ind1),
 
72
  vec:first(L1),ind1:second(L1),
 
73
  if ind1=0 then (ind1:dummy(),V([],[ind1])*diff(forma,ind1))
 
74
  else(
 
75
/* VTT: some black magic needed because MAXIMA doesn't handle ADDITIVE as expected */
 
76
  temp1:rename(forma@ind1),
 
77
  temp1:ev(temp1|_vec,noeval),
 
78
  temp1:ev(temp1,eval),
 
79
  temp2:rename(forma),
 
80
  temp2:ev(temp2|_vec,noeval),
 
81
  temp2:ev(temp2,eval)@ind1,
 
82
  temp1+temp2));
 
83