1 2% Redistribution and use in source and binary forms, with or without 3% modification, are permitted provided that the following conditions are met: 4% 5% * Redistributions of source code must retain the relevant copyright 6% notice, this list of conditions and the following disclaimer. 7% * Redistributions in binary form must reproduce the above copyright 8% notice, this list of conditions and the following disclaimer in the 9% documentation and/or other materials provided with the distribution. 10% 11% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 12% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 13% THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 14% PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNERS OR 15% CONTRIBUTORS 16% BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 17% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 18% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 19% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 20% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 21% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 22% POSSIBILITY OF SUCH DAMAGE. 23% 24 25COMMENT 26 27 The following routines can handle scalar expressions that are composed out 28 of 3-vectors in three different notations: 29 30 - the extended vector form: ABCD... stands for (A , B x (C x (D x ...))) 31 where ',' stands for the vector product and 'x' stands for the 32 skew symmetric product, 33 - the standard vector form involving only AB = (A , B) and 34 ABC = (A , B x C), 35 - the component form involving only the components a1,a2,a3,b1,... 36 37 In all 3 notations the vector is represented by a single letter only. 38 Any extra (non-vectorial) constant or parameter has to start with the 39 characters !&. 40 41 ROUTINES: 42 --------- 43 e2s : extended vector form into standard vector form, also conversion of a 44 standard vector form into standard vector form, but where factors 45 in calar products and triple products are sorted lexicographically, 46 This is necessary in order to work with this package on expressions 47 that have been generated outside this package. 48 v2c : any vector form (extended or standard) into component form 49 c2s : component form into standard vector form 50 c2sl: like c2s, only the resulting vector expression is returned partitioned 51 as a list which simplifies choosing arbitrary parameters arbcomplex(i) 52 such that the vector expression is as short as possible 53 s2s : generates and uses vector identities to length reduce a standard 54 vector form expression 55 s2e : like s2s but also uses identities involving n-products and thus 56 transforms standard vector form into extended vector form 57 genpro: generation of all scalar and spate products for a given vector list 58 genpro_wg: generation of all scalar and spate products with weight lists 59 for a given vector weight list 60 poisson_c: computation of the poisson bracket of two arbitrary 61 expressions, needs anything what struc_cons needs 62 in component form, e.g. kap:=-a1**2-a2**2-a3**2 63 poisson_v: computes the Poisson bracket for two vector expressions uses 64 global variables v_, gbase_ and initially the procedure 65 poisson_c (to compute the Poisson bracket between scalar and 66 spate products), so poisson_v needs all that poisson_c needs, 67 currently restricted to vectors A,B,U,V through gbase_ . 68 % arb2zero: sets all arbcomplex(1)..arbcomplex(!!arbint):=0 and !!arbint:=0 69 gfi: generates a vector expression with unknown coefficients, where 70 each term of the generated polynomial has a total weight list 71 as required by the first argument to gfi. The weight list of each 72 vector is given through the second argument to gfi. The third argument 73 is a list of vector expressions to the effect that no term of 74 the generated polynomial is purely a product of powers of these vector 75 exressions. gfi returns a list with the generated polynomial as first 76 element followed by a list of undetermined constants. 77 vinit: generates all polynomial identities for all scalar and triple 78 products from the (currently) 4 vectors in the input list 79 80 GLOBAL VARIABLES: 81 ----------------- 82 algebraic: all variables in struc_cons, like U1,U2,U3,V1,V2,V3,kap 83 v_, gbase_, heads_ % for poisson_v 84 !&c1, !&c2, ... % from c2s 85 operator: poi_ % stores the Poisson brackets 86 lisp: fino_, wgths_ % from file gengen.red 87 !&r1, !&r2, ... % from gfi 88 tr_vec 89 90 INITIALIZATION: 91 --------------- 92 This file contains all initializations (of v_,gbase_,heads_,struc_cons) 93 needed for computations with the 2 constant vectors A,B and 2 dynamical 94 vectors U,V. If other vectors or constant vectors with conditions, 95 like AB=0 should be used then 96 - run: vinit(list_of_vectors) 97$ 98 99lisp <<terpri()$ 100 write"********************************************************************"$ 101 terpri()$ 102 write"* Please note the following conventions to use these routines: *"$ 103 terpri()$ 104 write"* - Vectors are denoted by a single character and products *"$ 105 terpri()$ 106 write"* (A,Bx(Cx(Dx...))) by single identifiers ABCD... . For example, *"$ 107 terpri()$ 108 write"* scalar products (A,B) by AB, triple products (A,BxC) by ABC, *"$ 109 terpri()$ 110 write"* (A,Bx(CxD)) by ABCD and so on. For scalar and triple products *"$ 111 terpri()$ 112 write"* only those versions are used for which letters are sorted *"$ 113 terpri()$ 114 write"* alphabetically, for example, AB, ABU but not BA, AUB or BUA. *"$ 115 terpri()$ 116 write"* - Any non-vectorial variable starts with the two characters !&. *"$ 117 terpri()$ 118 write"* - For further comments see the beginning of this file and the *"$ 119 terpri()$ 120 write"* files v3tools.tex and v3tools.tst. *"$ 121 terpri()$ 122 write"********************************************************************"$ 123 terpri() 124>>$ 125 126lisp(if getd 'set_bndstk_size then set_bndstk_size(50000))$ 127load_package 'groebner$ 128load_package 'crack$ 129setcrackflags()$ 130symbolic fluid '(print_more record_hist max_gc_short size_watch max_gc_fac 131 print_ old_history tr_short tr_vec)$ 132tr_vec:=nil$ 133 134%---------------------------------------------------- 135 136algebraic operator poi_$ 137 138%---------------------------------------------------- 139symbolic fluid '(wgths_ fino_ nfct_)$ 140 141symbolic procedure gen(all)$ 142% The global variable wgths_ specifies the weights of the generated terms 143% which are put into the global list fino_. 144% 'all' is the list of variables and their weights to be used. 145% Before calling gen externally, set the global variable fino_ to nil. 146if null all then {cons(nil,for each h in wgths_ collect 0)} 147 % {{{'bu},0,1,1}} % i.e. if bu is an overall factor 148 % but then reductions are wrong 149 else begin 150 scalar h,v,vw,oldli,newli,vwcp,wgcp,found_less,found_more,b,c,d$ 151 152 h:=car all$ all:=cdr all$ 153 v:=car h; vw:=cdr h$ % the next factor to be multiplied + its weight-list 154 155 oldli:=gen(all)$ 156 % old has the form {e1,e2,e3,..} where 157 % ei = {{v1,v2,v3,..}, weights} represents a monomial 158 % vi are factors of the monomial, 159 % for all i: weights(i)<=wgths_(i) and not all relations are equalities. 160 161 while oldli do << 162 h:=car oldli; oldli:=cdr oldli$ 163 newli:=cons(h,newli); 164 repeat << 165 vwcp:=vw; 166 wgcp:=wgths_$ 167 found_less:=nil$ 168 found_more:=nil$ 169 h:=cons(cons(v,car h), 170 for each b in cdr h collect 171 <<d:=b+<<c:=car vwcp;vwcp:=cdr vwcp;c>>; 172 if d<car wgcp then found_less:=t else 173 if d>car wgcp then found_more:=t$ 174 wgcp:=cdr wgcp$ 175 d 176 >> 177 )$ 178 >> until if found_more then t else 179 if found_less=nil then 180 <<fino_:=cons(if cdar h then cons('times,car h) 181 else caar h ,fino_)$ t>> 182 else <<newli:=cons(h,newli); nil>> 183 >>$ 184 185 return newli 186end$ 187%---------------------------------------------------- 188 189algebraic procedure is_reduceable(trm,hs)$ 190begin 191 while hs neq {} and (den(trm/first hs) neq 1) do hs:=rest hs; 192 return if hs neq {} then t 193 else nil 194end$ 195 196%---------------------------------------------------- 197 198symbolic procedure l2s(li)$ 199% The program converts a list {a,b,c,d,..} which represents 200% (a,(bx(cx(dx..)))) where ',' stands for the scalar product and x 201% stands for the skew product into a polynomial of scalar products and 202% spate products. 203% The argument li must be a lisp list with at least 2 elements 204 205if length(li)=2 then if ordp(car li,cadr li) then mkid(car li,cadr li) 206 else mkid(cadr li,car li) 207 else 208if length(li)=3 then if (car li=cadr li) or 209 (car li=caddr li) or 210 (cadr li=caddr li) then 0 211 else 212if ordp(car li,cadr li) and 213 ordp(cadr li,caddr li) then mkid(car li,mkid(cadr li,caddr li)) else 214if ordp(cadr li,caddr li) and 215 ordp(caddr li,car li) then mkid(cadr li,mkid(caddr li,car li)) else 216if ordp(caddr li,car li) and 217 ordp(car li,cadr li) then mkid(caddr li,mkid(car li,cadr li)) else 218if ordp(car li,caddr li) and 219 ordp(caddr li,cadr li) then{'minus,mkid(car li,mkid(caddr li,cadr li))}else 220if ordp(cadr li,car li) and 221 ordp(car li,caddr li) then{'minus,mkid(cadr li,mkid(car li,caddr li))}else 222if ordp(caddr li,cadr li) and 223 ordp(cadr li,car li) then{'minus,mkid(caddr li,mkid(cadr li,car li))}else 224write"error in ord!" 225 else 226{'difference,{'times,if ordp(car li,caddr li) then 227 mkid(car li,caddr li) else 228 mkid(caddr li,car li),l2s(cons(cadr li,cdddr li))}, 229 {'times,if ordp(cadr li,caddr li) then 230 mkid(cadr li,caddr li) else 231 mkid(caddr li,cadr li),l2s(cons(car li,cdddr li))} }$ 232%---------------------------------------------------- 233 234%% symbolic procedure permu_repi(li)$ 235%% % generates a list of permutations of the elements of li without multiple 236%% % permutations but where li can have multiple elements 237%% begin scalar p,perm,red_perm$ 238%% perm:= 239%% if 1=length li then list(li) 240%% else for each x in li join 241%% for each y in permu_repi(delete(x,li)) collect cons(x,y)$ 242%% 243%% if perm and length car perm = 3 then << 244%% for each p in perm do 245%% if cadr p neq caddr p then red_perm:=cons(p,red_perm)$ 246%% perm:=red_perm; 247%% red_perm:=nil$ 248%% >>$ 249%% 250%% % deleting multiple lists 251%% for each p in perm do 252%% if not member(p,red_perm) then red_perm:=cons(p,red_perm)$ 253%% 254%% return red_perm 255%% end$ 256 257% FJW, May 2019: The following version of permu_repi caches function 258% values and generates only unique permutations. This makes it very 259% significantly more efficient when there are many repeated elements 260% in the list being permuted, as is the case when it is called in 261% v3tools.tst. Assuming this represents the normal use case then it 262% should be a worthwhile improvement. However, when there are no 263% repeats it will be slower and generate a lot of irrelevant 264% intermediate data. If this is an issue then it could be 265% conditionalized to pick the best strategy, so I have preserved the 266% original version above as a comment. 267 268fluid '(permu_repi_cache)$ 269 270symbolic procedure permu_repi(li)$ 271% generates a list of permutations of the elements of li without multiple 272% permutations but where li can have multiple elements 273begin scalar permu_repi_cache$ 274 % permu_repi_cache is used to avoid recursively recomputing 275 % the same sub-permutations within this call of permu_repi. 276 return permu_repi_1(li) 277end$ 278 279symbolic procedure permu_repi_1(li)$ 280begin scalar r,p,perm,red_perm, lix, xlix, perms_seen$ 281 % perms_seen is used to ignore duplicate permutations at this level. 282 if r:=assoc(li,permu_repi_cache) then return cdr r$ 283 perm:= 284 if 1=length li then list(li) 285 else for each x in li join << 286 lix := delete(x,li)$ xlix := x . lix$ 287 if not (xlix member perms_seen) then << 288 perms_seen := xlix . perms_seen$ 289 for each y in permu_repi_1 lix collect cons(x,y) >> 290 >>$ 291 292 if perm and length car perm = 3 then << 293 for each p in perm do 294 if cadr p neq caddr p then red_perm:=cons(p,red_perm)$ 295 perm:=red_perm; 296 >>$ 297 298 % This line is here only to preserve the ordering returned by the 299 % original version of this procedure: 300 perm:=reversip perm$ 301 302 permu_repi_cache:=(li.perm).permu_repi_cache$ 303 return perm 304end$ 305%---------------------------------------------------- 306 307symbolic procedure genid(vli,wgli)$ 308% This procedure generates a list of all n-vector products for given 309% vli : the list of vector variables and their weights 310% eg {{A,1,0},{B,1,0},{U,0,1},{V,1,1}} 311% wgli: the list of total weights of each term of the polynomial 312% eg {2,3} 313begin scalar h,hm,p,perm,allperm,idli,idlicp$ 314 315 fino_:=nil$ 316 wgths_:=wgli$ 317 gen(vli); 318 319 % now generation of all permutations 320 for each h in fino_ do << 321 % Each h is of the form {TIMES a a b b b u v v v ...} 322 write"Generating specific permutations of products of the vectors ", 323 compress cdr h,"."$ 324 terpri()$ 325 allperm:=permu_repi(cdr h)$ 326 write length allperm," permutations generated."$terpri()$ 327 328 % deleting multiple lists with identical first two elements 329 for each p in allperm do 330 if car p neq cadr p then perm:=cons(p,perm)$ 331 allperm:=nil$ 332 write"Applying another filter, ",length perm," are left."$terpri()$ 333 334 idli:=nil$ 335 for each p in perm do << 336 337 h:=reval l2s p$ 338 if not zerop h then << 339 hm:=reval {'minus,h}$ 340 idlicp:=idli$ 341 while idlicp and 342 caar idlicp neq h and 343 caar idlicp neq hm do idlicp:=cdr idlicp$ 344 345 if null idlicp then idli:=cons((h . intern compress p),idli) 346 >>$ 347 >>$ 348 write "At a first look ",length idli," seem to be non-equivalent."$terpri()$ 349% for each h in idli do mathprint {'EQUAL,cdr h,car h}$ 350 >>$ 351 fino_:=nil; 352 return for each h in idli collect {'difference,car h, cdr h} 353end$ 354%---------------------------------------------------- 355 356symbolic fluid '(algebraic_reduce_functions)$ 357lisp (algebraic_reduce_functions:= 358'(plus minus difference times quotient expt arbcomplex list))$ 359 360symbolic procedure expro(a)$ 361% procedure to extract all identifiers 362% the parameter a has to be in prefix form 363 364% WINFRIED: also, ich nehme immer die Funktion groebnervars 365% oder auch gvarlis wenn man sowieso das groebnerpackage 366% geladen hat. Eventuell groebnervars reval ... 367 368if null a then nil else 369if atom a then 370 if numberp a or 371 member(a,algebraic_reduce_functions) then nil 372 else {a} 373 else union(expro(car a),expro(cdr a))$ 374%---------------------------------------------------- 375 376symbolic procedure extract_prod(a)$ 377% extracts all identifiers from 'a' which do not start with &,!&,!! 378begin scalar ep,epl,h,ret$ 379 ep:=expro reval a$ 380 for each h in ep do << 381 epl:=explode h$ 382 if car epl neq '& and 383 car epl neq '!& and 384 car epl neq '!! then ret:=cons(h,ret) 385 >>$ 386 return ret 387end$ 388%---------------------------------------------------- 389 390symbolic operator e2s$ 391symbolic procedure e2s(a)$ 392% converts extended vector form to standard vector form 393% also useful to convert e.g. BA to AB if a vector expression has been 394% generated outside of this program 395begin scalar p,pl,px$ 396 pl:=extract_prod a$ 397 for each p in pl do << 398 px:=l2s explode p$ 399 if p neq px then a:=subst(px,p,a) 400 >>$ 401 return a 402end$ 403%---------------------------------------------------- 404 405symbolic procedure vc(v)$ 406% generates a lisp list of the 3 components for a given vector 407{mkid(v,1),mkid(v,2),mkid(v,3)}$ 408%---------------------------------------------------- 409 410symbolic procedure dot(f,g)$ 411% returns the scalar product of two vectors represented 412% by lisp lists of components 413reval {'plus,{'times,car f,car g}, 414 {'times,cadr f,cadr g}, 415 {'times,caddr f,caddr g} }$ 416%---------------------------------------------------- 417 418symbolic procedure cross(f,g)$ 419% returns the skew product of two vectors represented 420% by lisp lists of components 421{{'difference,{'times,cadr f,caddr g},{'times,caddr f,cadr g}}, 422 {'difference,{'times,caddr f,car g},{'times,car f,caddr g}}, 423 {'difference,{'times,car f,cadr g},{'times,cadr f,car g}} }$ 424%---------------------------------------------------- 425 426symbolic procedure spat(f,g,h)$ 427% returns the spate (triple) product of three vectors 428dot(f,cross(g,h))$ 429%---------------------------------------------------- 430 431symbolic operator v2c$ 432% converts any vector form into component form 433symbolic procedure v2c(a)$ 434begin scalar p,pl,px$ 435 if tr_vec then <<write"v2c start"$terpri()>>$ 436 a:=e2s a$ 437 pl:=extract_prod a$ 438 for each p in pl do << 439 px:=explode p$ 440 a:=subst(if length px = 2 then dot (vc car px,vc cadr px) 441 else spat(vc car px,vc cadr px,vc caddr px),p,a) 442 >>$ 443 if tr_vec then <<write"v2c end"$terpri()>>$ 444 return reval a 445end$ 446%---------------------------------------------------- 447 448symbolic procedure addvec(v,vl)$ 449% vl is an assoc list ((a . na) (b . nb) ...) of vectors a,b,... and the 450% number of their occurences na, nb, ... 451% An occurence of the vector v is added. 452begin scalar ve$ 453 ve:=assoc(v,vl)$ 454 return 455 if null ve then cons((v . 1),vl) 456 else cons((v . add1 cdr ve),delete(ve,vl)) 457end$ 458%---------------------------------------------------- 459 460symbolic procedure letters_of(a)$ 461% explodes an identifier and returns list of letters 462% if 'a' is a vector identifier and nil if 'a' is a parameter 463% (ie if 'a' starts with & or !& or !! ) 464begin scalar l,h,ea; 465 ea:=explode a$ 466 if car ea neq '& and 467 car ea neq '!& and 468 car ea neq '!! then 469 for each h in ea do 470 if freeof('(!0 !1 !2 !3 !4 !5 !6 !7 !8 !9),h) then l:=cons(h,l)$ 471 return l 472end$ 473%---------------------------------------------------- 474 475symbolic procedure get_vlist_of_term(at)$ 476% returns a sorted association list of vectors and their degree 477% appearing in the single term 'at' 478begin scalar f1,v,vl,vlc,h$ 479 if pairp at and car at = 'quotient then at:=cadr at; 480 if pairp at and car at = 'minus then << 481 at:=cadr at; 482 if pairp at and car at = 'quotient then at:=cadr at 483 >>$ 484 if pairp at and ((car at = 'times) or 485 (car at = 'list ) or 486 (car at = 'equal) ) then at:=cdr at 487 else at:={at}$ 488 while at do << 489 f1:=car at; at:=cdr at; 490 if not ((numberp f1 ) or 491 ((pairp f1) and 492 (car f1 = 'quotient) and 493 (numberp cadr f1) and 494 (numberp caddr f1) ) ) then 495 if atom f1 then for each v in letters_of f1 do vl:=addvec(v,vl) else 496 if car f1 neq 'arbcomplex then 497 if car f1 neq 'expt then write"****** car not EXPT ******" else 498 for each v in letters_of cadr f1 do 499 for h:=1:(caddr f1) do vl:=addvec(v,vl) 500 >>; 501 502 % at first sorting vl to generate later always the same vector 503 % products, like ab instead of ba 504 while vl do << 505 v:=car vl; 506 for each u in vl do if ordp(car v,car u) then v:=u; 507 vlc:=cons(v,vlc); 508 vl:=delete(v,vl); 509 >>$ 510 return vlc 511end$ 512%---------------------------------------------------- 513 514symbolic procedure filter_hom(a,at)$ 515% From the polynomial vector expression 'a' in component form return 516% 1) that part for which each term has the same number of occurences of the 517% same vector components as in the term 'at' 518% 2) the list of vectors and their number of occurences ((a.2) (b.1) ...) 519begin scalar vl,v,h,gs; 520 if tr_vec then <<write"filter_hom start"$terpri()>>$ 521 522 vl:=get_vlist_of_term(at)$ 523 gs:=gensym()$ 524 for each v in vl do << 525 % replace each component_of_car_v by gs**(component_of_car_v) 526 for each h in vc car v do a:=subst({'times,h,gs},h,a)$ 527 a:=reval a$ 528 a:=coeffn(a,gs,cdr v) 529 >>$ 530 531 if tr_vec then <<write"filter_hom end"$terpri()>>$ 532 return cons(a,vl) 533end$ 534%---------------------------------------------------- 535 536symbolic procedure t1(a)$ 537% 'a' is an expression in prefix form 538% t1 returns the first term of its numerator 539if null a then 0 else 540if atom a then a else 541if (car a='quotient) then reval {'quotient,t1 cadr a,caddr a} else 542if (car a='plus) or (car a='difference) then cadr a 543 else a$ 544%---------------------------------------------------- 545 546symbolic operator genpro_wg$ 547% converting algebraic input list to symbolic and result back to algebraic 548symbolic procedure genpro_wg(vl)$ 549cons('list,for each g in genpro_wg_l(for each h in cdr vl collect cdr h) 550 collect cons('list,g))$ 551%---------------------------------------------------- 552 553symbolic procedure addvectowg(wg,v)$ 554% adds vector v of weights to the vector wg 555for j:=1:(length wg) collect reval {'plus,nth(wg,j),nth(v,j)}$ 556%---------------------------------------------------- 557 558symbolic procedure genpro_wg_l(vl)$ 559% input: symbolic list of variables with weights, e.g. 560% vl={{A,1,0,0},{B,0,1,0},{U,0,0,1},{V,1,0,1}}$ 561% output: list of scalar/spate products + weights {{AA,2,0,0},..} 562if null vl then {'list} else 563begin scalar n,j,k,l,p2,p3,wg; 564 565 wg:=for j:=1:((length cdar vl)) collect 0$ 566 n:=length vl; 567 % then generation of the scalar products 568 p2:=for j:=1:n join 569 for k:=j:n collect 570 cons(mkid(car nth(vl,j),car nth(vl,k)), 571 addvectowg(addvectowg(wg,cdr nth(vl,j)),cdr nth(vl,k)))$ 572 573 % then generation of the spate products 574 p3:=for j:= 1 :(n-2) join 575 for k:=(j+1):(n-1) join 576 for l:=(k+1): n collect 577 cons(mkid(car nth(vl,j),mkid(car nth(vl,k),car nth(vl,l))), 578 addvectowg(addvectowg(addvectowg(wg,cdr nth(vl,j)), 579 cdr nth(vl,k)),cdr nth(vl,l)))$ 580 581 return append(p2,p3) 582end$ 583%---------------------------------------------------- 584 585symbolic procedure std_wg(vl)$ 586% lisp input : {a,b,u,v} 587% lisp output: {{a,1,0,0,0},{b,0,1,0,0},{u,0,0,1,0},{v,0,0,0,1}} 588for h:=1:(length vl) collect cons(nth(vl,h), 589for k:=1:(length vl) collect if h=k then 1 else 0)$ 590%---------------------------------------------------- 591 592symbolic operator genpro$ % moved up 593symbolic procedure genpro(vl)$ 594% input: algebraic list of vectors, e.g. {a,b,u,v} 595% output: algebraic list of scalar and spate products 596cons('list,for each h in genpro_wg_l(std_wg cdr vl) collect car h)$ 597%---------------------------------------------------- 598 599symbolic procedure hc2s(ahc)$ 600% generates a vector expression (if possible) for the homogeneaous 601% component expression car ahc 602% ahc={hom_expression_in_component_form,{('u.2),('v.1),..}} 603% where 2 is the degree of u,... 604begin scalar v,vl,nf,f,fl,zro,h,sol,ansatz$ %,oldorder$ 605 if tr_vec then <<write"hc2s start"$terpri()>>$ 606 607 % generation of all vector products with correct weight 608 fino_:=nil$ 609 wgths_:=for each v in cdr ahc collect cdr v$ 610 if tr_vec then << write"gen start"$terpri()>>$ 611 gen genpro_wg_l std_wg for each v in cdr ahc collect car v$ 612 if tr_vec then <<write"gen end"$terpri()>>$ 613 614 % generating a vector ansatz with unknown coefficients 615 nf:=1; 616 ansatz:=for each v in fino_ collect << 617 f:=mkid('!&c,nf); 618 nf:=add1 nf$ 619 fl:=cons(f,fl); 620 {'times,f,v} 621 >>$ 622 fino_:=nil; 623 if tr_vec then << 624 write"The vector ansatz has ",length fl," unknown coefficients."$terpri() 625 >>$ 626 if null cdr ansatz then ansatz:=reval car ansatz 627 else ansatz:=reval cons('plus,ansatz)$ 628 629 % generate a list vl of all components of all vectors 630 vl:=for each v in cdr ahc join vc car v$ 631 632% oldorder:=setkorder vl; 633 634 zro:={'list,reval {'difference,car ahc,v2c ansatz}}$ 635 636 % splitting zro: 637 638 for each v in vl do << 639 if tr_vec then <<write"splitting wrt ",v$terpri()>>$ 640 sol:=cdr algebraic(for each h in lisp(zro) join coeff(lisp h,lisp v)); 641 % deleting zeros 642 zro:=nil$ 643 while sol do << 644 if car sol neq 0 then zro:=cons(car sol,zro); 645 sol:=cdr sol$ 646 >>$ 647 if tr_vec then <<write"zro has ",length zro," conditions."$terpri()>>$ 648 zro:=cons('list,zro) 649 >>$ 650 if tr_vec then << 651 write (length zro) - 1," conditions for ",length fl," unknowns."$terpri() 652 >>$ 653 654 % solution of the condition: 655 !!arbint:=0$ 656 if tr_vec then <<write"solveeval start"$terpri()>>$ 657 sol:=solveeval list(zro,cons('list,fl)); 658 if tr_vec then <<write"solveeval end"$terpri()>>$ 659 660 return 661 if null cdr sol then nil 662 else algebraic << 663 664 ansatz:=sub(first lisp sol,lisp ansatz)$ 665 666 zro:=0$ 667 sol:=for h:=1:lisp !!arbint collect << 668 v:=coeffn(ansatz,arbcomplex(h),1)$ 669 zro:=zro+arbcomplex(h)*v$ 670 num v 671 >>$ 672 ansatz:=ansatz-zro$ 673 674 % Call of CRACK to shorten the identities 675 if t then << 676 off batch_mode$ 677 lisp << 678 print_more:=nil; 679 record_hist:=t; 680 max_gc_short:=15; % 25; 681 size_watch:=t; 682 max_gc_fac:=4; 683 print_:=nil$ 684 old_history:='(l 11 !; q 0)$ 685 >>$ 686 sol:=crack(sol,{},lisp cons('list,extract_prod(sol)),{}); 687 >>$ 688 689 lisp(if tr_vec then <<write"hc2s end"$terpri()>>)$ 690 cons(ansatz,first first sol) 691 >> 692end$ 693%---------------------------------------------------- 694 695algebraic procedure c2s(a)$ 696begin scalar n$ 697 return << 698 n:=0; 699 for each h in c2sl(a) sum 700 first h + for each g in rest h sum << 701 n:=n+1; 702 (lisp mkid('!&c,reval algebraic n))*g 703 >> 704 >> 705end$ 706%---------------------------------------------------- 707 708symbolic operator c2sl$ 709symbolic procedure c2sl(a)$ 710% converts a possibly inhom. vector expression 'a' into standard vector form 711begin scalar av,ahv,ahc,at1,tr_vec$ 712 if tr_vec then <<write"c2sl start"$terpri()>>$ 713 tr_vec:=nil$ 714 a:=reval a$ 715 av:={}$ ahv:=1$ 716 while (a neq 0) and ahv do << 717 718 % pick the first term 719 at1:=t1 a$ 720 if tr_vec then <<write length a," terms to vectorize."$terpri()>>$ 721 722 % extract all terms of type at1 723 ahc:=filter_hom(a,at1)$ % includes assoc list of vectors + degree 724 725 ahv:=hc2s ahc$ 726 if ahv then <<av:=cons(ahv,av); a:=reval {'difference,a,car ahc}>> 727 else <<write"All the terms with the same homogeneity as the"$ 728 terpri()$ 729 write"following terms can not be vectorized: "$ 730 mathprint at1>> 731 >>$ 732 733 return 734 if null ahv then nil 735 else << 736 if tr_vec then << 737 terpri()$ 738 write"The input expression in component form has been partitioned. Each of"$ 739 terpri()$ 740 write"the partitions Pi has been converted into vector form and comes with"$ 741 terpri()$ 742 write"identities Iij of the same homogeneity type to be used to shorten Pi."$ 743 terpri()$ 744 write"Everything is returned in the form {{P1,I11,I12,..},{P2,I21,..},..}."$ 745 terpri() 746 >>$ 747 if tr_vec then <<write"c2sl stop"$terpri()>>$ 748 reval cons('list,av) 749 >>$ 750 751end$ 752%---------------------------------------------------- 753 754symbolic procedure add_hom_term(v,at,pl)$ 755% pl is an assoc list ((vl1 . terms1) (vl2 . terms2) ...) where 756% vli are assoc lists of vectors and their appearance and terms1 the sum of all 757% terms with these vectors 758% In this procedure an occurence of the pair (v . at) is added. 759begin scalar plc$ 760 while pl and (caar pl neq v) do <<plc:=cons(car pl,plc);pl:=cdr pl>>$ 761 if null pl then plc:=cons((v . at),plc) 762 else << 763 plc:=cons((v . {'plus,cdar pl,at}),plc); 764 pl:=cdr pl; 765 while pl do <<plc:=cons(car pl,plc);pl:=cdr pl>> 766 >>$ 767 return plc 768end$ 769%---------------------------------------------------- 770 771symbolic procedure shortvex(a,d)$ 772% generates and uses vector identities to length reduce standard vector 773% form expressions 774% if d<>nil then it also uses identities involving n-products and thus 775% transforms the standard vector form expression 'a' into extended vector form 776begin scalar at1,pl,sh,n,wg,j,k,vli,wli,vlc,idty,gs$ 777 778 % partition 'a' into parts where within each all terms have the same 779 % number of the same vectors 780 a:=reval a$ 781 while a neq 0 do << 782 783 % pick the first term 784 at1:=t1 a$ 785 786 % add at1 to the right partition 787 pl:=add_hom_term(get_vlist_of_term(at1),at1,pl)$ 788 789 a:=reval {'difference,a,at1} 790 >>$ 791 792 % optimize the formulation in terms of n-products for each single partition 793 while pl do << 794 vlc:=caar pl; sh:=cdar pl; pl:=cdr pl; 795 if d then << 796 n:=length vlc; 797 k:=0; 798 vli:=nil; wli:=nil; 799 while vlc do << 800 k:=add1 k; 801 wg:=append(for j:=1:(k-1) collect 0,cons(1,for j:=(k+1):n collect 0))$ 802 vli:=cons(cons(caar vlc,wg),vli); 803 wli:=cons(cdar vlc,wli); 804 vlc:=cdr vlc 805 >>$ 806 >>$ 807 808 algebraic write"=========================================================="$ 809 algebraic write"One partition of input: ",lisp sh$ 810 811 % sh contains a specific combination of vectors encoded in vli and wli. 812 % For this combination of vectors all identities are generated next: 813 algebraic (% write"a) identities: ", 814 idty:=rest first c2sl v2c lisp t1 sh); 815 816 % now identities are generated that contain each one n-vector product 817 % expressed in terms of scalar and triple products: 818 gs:=gensym()$ 819 idty:=cons('list, 820 cons(reval {'difference,sh,gs}, 821 if d then append(cdr idty,genid(reverse vli,reverse wli)) 822 else cdr idty 823 ))$ 824 825%write"idty="$prettyprint idty$ 826 algebraic off batch_mode$ 827 print_more:=nil; 828 record_hist:=t; 829 max_gc_short:=15; % 25; 830 size_watch:=t; 831 max_gc_fac:=4; 832 print_:=nil$ 833%print_:=100000$ 834 tr_short:=t$ 835 old_history:='(67 e_1 nil q 0)$ 836%old_history:=nil$ 837 idty:=algebraic(crack(idty,{},lisp cons('list,extract_prod(idty)),{})); 838 if idty={'list} then <<write"ERROR 1 in CRACK!"$terpri()>> 839 else << 840 idty:=cadr cadr idty; % the remaining equations from the first solution 841 while idty and freeof(car idty,gs) do idty:=cdr idty; 842 if null idty then <<write"ERROR 2 in CRACK!"$terpri()>> 843 else << 844 idty:=solveeval list(car idty,{'list,gs}); 845 if null idty or (idty={'list}) then <<write"ERROR 3 in SOLVE!"$terpri()>> 846 else << 847 idty:=caddr cadr idty$ 848 if 0=reval reval {'difference,sh,idty} then 849 write"Partition is unchanged." else << 850 write"shortened expression:"; 851 mathprint idty % rhs of first solution 852 >> 853 >> 854 >> 855 >>$ 856 857 a:=algebraic(a+idty)$ 858 859 % to save memory (for now): 860 idty:=nil 861 862 >>$ 863 return a 864end$ 865%---------------------------------------------------- 866 867symbolic operator s2s$ 868symbolic procedure s2s(a)$ 869shortvex(a,nil)$ 870%---------------------------------------------------- 871 872symbolic operator s2e$ 873symbolic procedure s2e(a)$ 874shortvex(a,t)$ 875%---------------------------------------------------- 876 877% not anymore used: 878%symbolic operator arb2zero$ 879%symbolic procedure arb2zero(a)$ 880%begin scalar h$ 881% for h:=1:!!arbint do a:=algebraic(sub(arbcomplex(h)=0,a))$ 882% !!arbint:=0$ 883% return a 884%end$ 885%---------------------------------------------------- 886 887algebraic procedure poisson_c(f,g,poi_struc_mat)$ 888% computes Poisson bracket for arbitrary expressions F,G 889% using the Poisson structure matrix poi_struc_mat 890for each h in poi_struc_mat sum (df(f,first h)*df(g,second h)- 891 df(g,first h)*df(f,second h) )*(third h)$ 892%---------------------------------------------------- 893 894algebraic procedure poisson_v(f,g,poi_struc_mat)$ 895% computes the numerator of the Poisson bracket for vector expressions F,G 896% using the Poisson structure matrix poi_struc_mat. 897% It uses the global variables v_ (algebraic list of vectors) and gbase_ (an 898% algebraic Groebner basis of the identities between vectors v_). 899% If the poisson bracket for the dynamical variables (the operator poi_) is 900% not yet computed then they are initially computed in component form and for 901% that this procedure needs all relations between identifiers in the structure 902% matrix (like in the default settings kap) assigned in component form, 903% e.g. kap:=-a1**2-a2**2-a3**2$ 904begin scalar h,r,s,alle$ 905 alle:=reverse genpro(v_)$ 906 torder(alle,lex)$ 907 lisp(!!arbint:=0)$ 908 h:=for each r in alle sum for each s in alle sum 909 if r=s then <<poi_(r,s):=0;0>> 910 else <<if (arglength poi_(r,s) = 2) and 911 (part(poi_(r,s),0) = poi_) then 912 poi_(r,s):=for each h in c2sl poisson_c(v2c r,v2c s, 913 poi_struc_mat) 914 sum first h$ 915 poi_(r,s)*df(f,r)*df(g,s)>>$ 916 917 r:=preduce(num h,gbase_); 918 return 919 r 920 % The following was commented out as computing the quotient r/s 921 % can take too much memory, much more than needed for solving r=0 later 922 % 923 % if den h neq 1 then << 924 % s:=preduce(den h,gbase_); 925 % if s=0 then write"Error: Poisson bracket has zero denominator!" 926 % else r/s 927 % >> else r 928end$ 929 930% Typical use: 931% 932% hh:={poisson_v(F,G, 933% {{U1,U2, U3}, {U2,U3, U1}, {U3,U1, U2}, 934% {U1,V2, V3}, {U2,V3, V1}, {U3,V1, V2}, 935% {U1,V3,-V2}, {U2,V1,-V3}, {U3,V2,-V1}, 936% {V1,V2, kap*U3}, {V2,V3, kap*U1}, {V3,V1, kap*U2}})}; 937% for each g in genpro {a,b,u,v} do 938% hh:=for each h in hh join coeff(h,g)$ 939%---------------------------------------------------- 940 941symbolic procedure symaddweights(vwghts,exl)$ 942% vweights is an algebraic list like {{a,1,0,0},{b,0,1,0},{u,0,0,1},{v,1,0,1}} 943% exl is a list of homogeneous standard vector expressions 944% The procedure returns a lisp list of lisp lists like vweights, 945% only with the exl-expressions instead of vectors as first elements of 946% the sub-lists. 947 948begin scalar h,g,k,wg,p,v,n$ 949 return 950 for each h in cdr exl collect << 951 h:=reval h; 952 g:=t1 h$ 953 k:=get_vlist_of_term g$ % k is an assoc list of all vectors with 954 % their multiplicity 955 wg:=for each p in cddadr vwghts collect 0$ 956 while k do << 957 p:=car k; k:=cdr k; 958 v:=cdr vwghts; 959 while v and cadar v neq car p do v:=cdr v; 960 v:=cddar v; % v is the weight list of car p 961 for n:=1:cdr p do wg:=addvectowg(wg,v) 962 >>$ 963 964 cons(h,wg) 965 >> 966end$ 967%---------------------------------------------------- 968 969symbolic operator addweights$ 970symbolic procedure addweights(vwghts,exl)$ 971% The same as symaddweights, only returning an algebraic list of alg. lists 972cons('list,for each h in symaddweights(vwghts,exl) collect cons('list,h))$ 973%---------------------------------------------------- 974 975lisp(nfct_:=1)$ % defined in crack 976 977symbolic operator gfi$ 978symbolic procedure gfi(wgcp,alle,fdep,heads)$ 979begin scalar k,g,h,p,rtn,dropped1,dropped2,f,fl,gt1$ 980 % - If one wants a specific factor then this factor has to be multiplied 981 % afterwards and gfi has to be given appropriate lowered weights 982 % - dropped1 is the number of terms dropped as they can be replaced 983 % using products of powers of Casimirs, Hamiltonians and known 984 % first integrals. 985 % - dropped2 is the number of terms dropped due to general relationships 986 % of 3-component vectors. 987 988 % At first we generate all possible terms with proper multi-weight 989 wgths_:=cdr wgcp$ 990 fino_:=nil$ 991 gen(for each h in cdr reval algebraic genpro_wg alle collect cdr h); 992 993 % Then we drop all terms that are reducible due to identities 994 dropped2:=0; 995 while fino_ do << 996 h:=reval car fino_; fino_:=cdr fino_; 997 if algebraic is_reduceable(lisp h,heads) then dropped2:=add1 dropped2 998 else rtn:=cons(h,rtn) 999 >>$ 1000 1001 % Now we drop all terms that could be killed through expressions 1002 % functionally dependent on expressions in fdep 1003 1004 % 1. finding and adding the weight lists producing a lisp list of lisp lists 1005 fdep:=symaddweights(alle,fdep)$ 1006 1007 dropped1:=0; 1008 fino_:=nil$ 1009 gen fdep; 1010 for each h in fino_ do << % i.e. for each functionally dependent expression 1011 h:=reval h$ 1012 h:=if not pairp h then list h else 1013 if (car h='plus) or (car h='difference) then cdr h else list h; 1014 gt1:=nil$ 1015 1016 while h do << 1017 g:=car h$ h:=cdr h$ % g is one term of the funct. dep. expression 1018 % drop minus sign 1019 if pairp g and car g='minus then g:=cadr g; 1020 % drop numerical denominator 1021 if pairp g and car g='quotient and numberp caddr g then g:=cadr g; 1022 % drop numerical factor 1023 if pairp g and car g='times then << 1024 p:=nil; 1025 for each k in cdr g do % i.e. for each factor 1026 if numberp k or 1027 (pairp k and 1028 car k = 'quotient and 1029 numberp cadr k and 1030 numberp caddr k) then p:=cons(k,p); 1031 if p then << 1032 if cdr p then p:=cons('times,p) 1033 else p:=car p; 1034 g:=reval {'quotient,g,p} 1035 >> 1036 >>$ 1037 if null member(g,rtn) then <<gt1:=nil; % hcp is not contained in ansatz 1038 h:=nil>> % to stop looking at further terms 1039 else if null gt1 then gt1:=g 1040 >>$ % all terms of h have been looked at 1041 if gt1 then << % funct. dep. expression is still in the ansatz, 1042 % --> drop gt1 from ansatz 1043 dropped1:=add1 dropped1$ 1044 rtn:=delete(gt1,rtn) 1045 >>$ 1046 1047 >>$ 1048 1049 % The remaining terms get an undetermined coefficient and are added up 1050 fino_:=rtn$ rtn:=nil$ 1051 while fino_ do << 1052 h:=reval car fino_; fino_:=cdr fino_; 1053 f:=mkid('!&r,nfct_)$ 1054 nfct_:=add1 nfct_$ 1055 fl:=cons(f,fl)$ 1056 rtn:=cons({'times,f,h},rtn) 1057 >>$ 1058 1059 if tr_vec then 1060 write"dropped: ",dropped1,"+",dropped2," kept: ",length rtn$ 1061 return reval 1062 cons('list,if null rtn then nil else 1063 cons(if cdr rtn then cons('plus,rtn) 1064 else car rtn, 1065 fl)) 1066end$ 1067%---------------------------------------------------- 1068 1069algebraic procedure gpi(wgl,vl,gbase)$ 1070% subroutine to generate polynomial identities between vectors 1071% as used by vinit(). 1072begin scalar hh,vcl,id,fl,g,h$ 1073 hh:=lisp(cons('list,for each h in std_wg(cdr vl) collect 1074 cons('list,h))); 1075 hh:=gfi(wgl,hh,{},{}); 1076 if hh neq {} then << 1077 id:=first hh$ 1078 fl:=rest hh$ 1079 hh:={v2c id}$ 1080 vcl:=for each h in vl join lisp cons('list,vc reval h); 1081 for each g in vcl do 1082 hh:=for each h in hh join coeff(h,g)$ 1083 lisp(!!arbint:=0)$ 1084 hh:=solve(hh,fl)$ 1085 id:=sub(first hh,id); 1086 id:=for h:=1:lisp(!!arbint) collect num coeffn(id,arbcomplex(h),1); 1087 1088 for each h in id do 1089 if not fixp h then 1090 if gbase={} then gbase:={h} 1091 else << 1092 h:=preduce(h,gbase); 1093 if h neq 0 then gbase:=groebner(cons(h,gbase)) 1094 >> 1095 >>; 1096 return gbase 1097end$ 1098%---------------------------------------------------- 1099 1100algebraic procedure vinit(alle)$ 1101% generates all polynomial identities gbase_ for all scalar and triple 1102% products from the 4 vectors in the list alle 1103begin scalar i,j,k,l,natbak$ 1104 v_:=alle$ 1105 torder(reverse genpro v_,lex)$ 1106 gbase_:={}; 1107 on gltbasis$ 1108 for i:=0:3 do % here for exactly 4 vectors 1109 for j:=0:3 do 1110 for k:=0:3 do 1111 for l:=0:3 do 1112 if ((i+j+k+l)> 0) and 1113 ((i+j+k+l)<11) then gbase_:=gpi({i,j,k,l},v_,gbase_)$ 1114 heads_:=gltp$ 1115 on nat 1116end$ 1117%---------------------------------------------------- 1118 1119symbolic procedure wg_li(a,vlw)$ 1120% checks whether expression 'a' is homogeneous wrt to vlw which 1121% is a list of variables with weights, e.g. 1122% vlw=((A 1 0 0) (B 0 1 0) (U 0 0 1) (V 1 0 1))$ 1123% and in this case return the weightlist of 'a' 1124% It assumes the expression is a polynomial in the vectors, so any 1125% denominator is disregarded. 1126begin scalar wg,at1,h,wl,n,vlwcp,errorcd,m$ 1127 a:=reval a$ 1128 if pairp a and car a = 'quotient then a:=cadr a$ 1129 a:=if pairp a and car a = 'plus then cdr a 1130 else list a$ 1131 1132 repeat << 1133 at1:=car a$ a:=cdr a$ 1134 h:=get_vlist_of_term(at1)$ % e.g. ((a . 1) (b . 1) (u . 2)) 1135 1136 % to get total weightlist wl of the term el1 add for each vector its 1137 % weightlist times its multiplicity 1138 wl:=for n:=1:(length cdar vlw) collect 0; 1139 while h do << 1140 vlwcp:=vlw$ 1141 while vlwcp and ((caar vlwcp) neq (caar h)) do vlwcp:=cdr vlwcp; 1142 if null vlwcp then <<errorcd:=1; 1143 write"Unspecified vector ",caar h," found!"$ 1144 terpri()>> 1145 else for m:=1:(cdar h) do wl:=addvectowg(wl,cdar vlwcp)$ 1146 % adds weightlist of caar h to the vector wl 1147 h:=cdr h 1148 >>$ 1149 1150 if null wg then wg:=wl else 1151 if wg neq wl then <<errorcd:=2;write"Expression is inhomogeneous!"$terpri()>> 1152 >> until null a or errorcd; 1153 return 1154 if errorcd then nil 1155 else wg 1156end$ 1157%---------------------------------------------------- 1158 1159symbolic operator fnc_dep$ 1160symbolic procedure fnc_dep(a,li,vlw)$ 1161% investigates whether 'a' is functionally 1162% independent of the elements of the list li or not. 1163% vlw is a list of variables with weights, e.g. 1164% vlw={{A,1,0,0},{B,0,1,0},{U,0,0,1},{V,1,0,1}}$ 1165% It uses the global variables v_ (algebraic list of vectors) and gbase_ (an 1166% algebraic Groebner basis of the identities between vectors v_). 1167begin scalar el,h,subli1,subli2,g,para,f,cnd,fl,ansatz,pl,n$ 1168 1169 vlw:=for each el in cdr vlw collect cdr el; 1170 % check homogeneity of 'a' and each element el of li and 1171 % prepare a weight list for 'a' and el 1172 wgths_:=wg_li(a,vlw)$ 1173 1174 h:=for each g in wgths_ sum g; 1175 if zerop h then return nil; 1176 1177 n:=0; 1178 for each el in cdr li do << 1179 h:=gensym()$ 1180 subli1:=cons({'equal,h,el},subli1); 1181 n:=add1 n$ 1182 subli2:=cons({'equal,h,mkid('p_,n)},subli2); 1183 g:=wg_li(el,vlw)$ 1184 para:=cons(cons(h,g),para) 1185 >>$ 1186 subli1:=cons('list,subli1)$ 1187 subli2:=cons('list,subli2)$ 1188 1189 fino_:=nil;gen para; 1190 1191 if null fino_ then return nil$ 1192 % write"wgths_=",wgths_$terpri()$ 1193 % write"subli1=",subli1$ terpri()$ 1194 % write"subli2=",subli2$ terpri()$ 1195 % write"para=",para$ terpri()$ 1196 1197 while fino_ do << 1198 h:=reval car fino_; fino_:=cdr fino_; 1199 f:=mkid('!&r,nfct_)$ 1200 nfct_:=add1 nfct_$ 1201 fl:=cons(f,fl)$ 1202 ansatz:=cons({'times,f,h},ansatz) 1203 >>$ 1204 fl:=cons('list,fl)$ 1205 ansatz:=cons('plus,ansatz); 1206 cnd:=reval {'difference,a,algebraic(sub(subli1,lisp ansatz))}; 1207 1208 return 1209 algebraic << 1210 1211 pl:=reverse genpro(v_)$ 1212 torder(pl,lex)$ 1213 cnd:={preduce(cnd,gbase_)}$ 1214 for each g in pl do 1215 cnd:=for each h in cnd join coeff(h,g)$ 1216 1217 h:=solve(cnd,fl)$ 1218 1219 if h neq {} then << 1220 lisp << 1221 write "The expression in question is functionally dependent on"$ 1222 terpri()$ 1223 write "the list of expressions {p_1,p_2,...} in the following way:"$ 1224 >>$ 1225 write sub(subli2,sub(first h,ansatz)); 1226 t 1227 >> else nil 1228 >> 1229 1230end$ 1231%---------------------------------------------------- 1232 1233algebraic << 1234v_:={a,b,u,v}$ 1235 1236torder(reverse genpro v_,lex)$ 1237 1238gbase_ :={ - bb*uu*vv + bb*uv**2 + bu**2*vv - 2*bu*bv*uv + buv**2 + bv**2*uu, 1239 - ab*uu*vv + ab*uv**2 + au*bu*vv - au*bv*uv + auv*buv - av*bu*uv + av*bv*uu, 1240 - ab*bu*vv + ab*bv*uv + abv*buv + au*bb*vv - au*bv**2 - av*bb*uv + av*bu*bv, 1241 - ab*bu*uv + ab*bv*uu + abu*buv + au*bb*uv - au*bu*bv - av*bb*uu + av*bu**2, 1242 - abu*vv + abv*uv - auv*bv + av*buv, 1243 - abu*uv + abv*uu + au*buv - auv*bu, 1244ab*buv - abu*bv + abv*bu - auv*bb, 1245aa*buv - ab*auv - abu*av + abv*au, 1246 - aa*uu*vv + aa*uv**2 + au**2*vv - 2*au*av*uv + auv**2 + av**2*uu, 1247 - aa*bu*vv + aa*bv*uv + ab*au*vv - ab*av*uv + abv*auv - au*av*bv + av**2*bu, 1248 - aa*bu*uv + aa*bv*uu + ab*au*uv - ab*av*uu + abu*auv - au**2*bv + au*av*bu, 1249abu*au*vv - abu*av*uv - abv*au*uv + abv*av*uu + au*auv*bv - auv*av*bu, 1250ab*abu*vv - ab*abv*uv + ab*auv*bv - abu*av*bv + abv*av*bu - auv*av*bb, 1251aa*abu*vv - aa*abv*uv + aa*auv*bv - ab*auv*av - abu*av**2 + abv*au*av, 1252ab*abu*uv - ab*abv*uu + ab*auv*bu - abu*au*bv + abv*au*bu - au*auv*bb, 1253aa*abu*uv - aa*abv*uu + aa*auv*bu - ab*au*auv - abu*au*av + abv*au**2, 1254aa*abu*bv - aa*abv*bu + aa*auv*bb - ab**2*auv - ab*abu*av + ab*abv*au, 1255 - aa*bb*vv + aa*bv**2 + ab**2*vv - 2*ab*av*bv + abv**2 + av**2*bb, 1256 - aa*bb*uv + aa*bu*bv + ab**2*uv - ab*au*bv - ab*av*bu + abu*abv + au*av*bb, 1257 - ab*abu*bu*vv + ab*abu*bv*uv + ab*abv*bu*uv - ab*abv*bv*uu + abu*au*bb*vv - 1258abu*au*bv**2 - abu*av*bb*uv + abu*av*bu*bv - abv*au*bb*uv + abv*au*bu*bv + 1259abv*av*bb*uu - abv*av*bu**2, 1260 - aa*abu*bu*vv + aa*abu*bv*uv + aa*abv*bu*uv - aa*abv*bv*uu + ab*abu*au*vv - 1261ab*abu*av*uv - ab*abv*au*uv + ab*abv*av*uu - abu*au*av*bv + abu*av**2*bu + 1262abv*au**2*bv - abv*au*av*bu, 1263 - aa*abu*bb*vv + aa*abu*bv**2 + aa*abv*bb*uv - aa*abv*bu*bv + ab**2*abu*vv - 1264ab**2*abv*uv - 2*ab*abu*av*bv + ab*abv*au*bv + ab*abv*av*bu + abu*av**2*bb - 1265abv*au*av*bb, 1266 - aa*abu*bb*uv + aa*abu*bu*bv + aa*abv*bb*uu - aa*abv*bu**2 + ab**2*abu*uv - 1267ab**2*abv*uu - ab*abu*au*bv - ab*abu*av*bu + 2*ab*abv*au*bu + abu*au*av*bb - 1268abv*au**2*bb, 1269 - aa*bb*uu + aa*bu**2 + ab**2*uu - 2*ab*au*bu + abu**2 + au**2*bb, 1270aa*bb*uu*vv - aa*bb*uv**2 - aa*bu**2*vv + 2*aa*bu*bv*uv - aa*bv**2*uu - 1271ab**2*uu*vv + ab**2*uv**2 + 2*ab*au*bu*vv - 2*ab*au*bv*uv - 2*ab*av*bu*uv + 12722*ab*av*bv*uu - au**2*bb*vv + au**2*bv**2 + 2*au*av*bb*uv - 2*au*av*bu*bv - 1273av**2*bb*uu + av**2*bu**2}$ 1274 1275heads_ := 1276{buv**2,auv*buv,abv*buv,abu*buv,av*buv,au*buv,ab*buv,aa*buv,auv**2,abv*auv, 1277abu*auv,au*auv*bv,ab*auv*bv,aa*auv*bv,ab*auv*bu,aa*auv*bu,aa*auv*bb,abv**2,abu 1278*abv,ab*abv*bu*uv,aa*abv*bu*uv,aa*abv*bb*uv,aa*abv*bb*uu,abu**2,aa*bb*uu*vv}$ 1279 1280>>; 1281 1282% kap:=!&eta**2$ 1283% kap:=-a1**2-a2**2-a3**2$ 1284% 1285% so(4),so(3,1),e(3) 1286% STRUC_CONS:={{U1,U2, U3}, {U2,U3, U1}, {U3,U1, U2}, 1287% {U1,V2, V3}, {U2,V3, V1}, {U3,V1, V2}, 1288% {U1,V3,-V2}, {U2,V1,-V3}, {U3,V2,-V1}, 1289% {V1,V2, kap*U3}, {V2,V3, kap*U1}, {V3,V1, kap*U2}}$ 1290% 1291% so(3): 1292% STRUC_CONS:={{U1,U2, U3}, {U2,U3, U1}, {U3,U1, U2}}$ 1293% 1294% e(3): 1295% STRUC_CONS:={{U1,U2, U3}, {U2,U3, U1}, {U3,U1, U2}, 1296% {U1,V2, V3}, {U2,V3, V1}, {U3,V1, V2}, 1297% {U1,V3,-V2}, {U2,V1,-V3}, {U3,V2,-V1} }$ 1298% 1299% so(4): 1300% STRUC_CONS:={{U1,U2, U3}, {U2,U3, U1}, {U3,U1, U2}, 1301% {U1,V2, V3}, {U2,V3, V1}, {U3,V1, V2}, 1302% {U1,V3,-V2}, {U2,V1,-V3}, {U3,V2,-V1}, 1303% {V1,V2, U3}, {V2,V3, U1}, {V3,V1, U2} }$ 1304% 1305% so(3,1): 1306% STRUC_CONS:={{U1,U2, U3}, {U2,U3, U1}, {U3,U1, U2}, 1307% {U1,V2, V3}, {U2,V3, V1}, {U3,V1, V2}, 1308% {U1,V3,-V2}, {U2,V1,-V3}, {U3,V2,-V1}, 1309% {V1,V2,-U3}, {V2,V3,-U1}, {V3,V1,-U2} }$ 1310% 1311% so(3)^2: 1312% STRUC_CONS:={{U1,U2, U3}, {U2,U3, U1}, {U3,U1, U2}, 1313% {V1,V2, V3}, {V2,V3, V1}, {V3,V1, V2} }$ 1314 1315end$ 1316