source: git/Singular/LIB/difform.lib @ 6b5e56

fieker-DuValspielwiese
Last change on this file since 6b5e56 was 166e908, checked in by Hans Schoenemann <hannes@…>, 8 years ago
fix: version of new libs
  • Property mode set to 100644
File size: 90.3 KB
Line 
1////////////////////////////////////////////////////////////////////////////////
2version="version difform.lib 1.0.0.2 Apr_2015 "; // $Id$
3category="Noncommutative";
4info="
5LIBRARY:   difform.lib Procedures for differential forms
6AUTHOR:    Peter Chini,        chini@rhrk.uni-kl.de
7
8OVERVIEW:
9A library for computing with elements of the differential algebra over a (quotient) ring.
10To compute in this algebra, a non-commutative ring with additional variables
11dx_1,...,dx_n and 'exterior' relations between this variables is used. In the case of a
12quotient ring, the defining ideal and its image under the universal derivation are added as relations.
13The differential forms themselves are defined via an additional type 'difform'. Objects
14of this type carry as an attribute a polynomial in the differential algebra and make it
15available over the basering.
16Additionally, the universal derivation is available as a procedure and the differentials between the
17graded parts of the differential algebra can be applied to differential forms.
18The library also supports derivations: maps from the first graded part of the differential algebra
19to the basering. These are defined via the type 'derivation' and there are procedures for basic arithmetic
20operations, evaluation and Lie-derivative.
21
22PROCEDURES:
23    diffAlgebra();                  provides the differential algebra structure and the differential forms dx_1,...,dx_n
24    diffAlgebraStructure();         generates the structure of the differential algebra from the basering
25    diffAlgebraCheck();             checks if the basering already has a differential algebra
26    diffAlgebraSwitch();            changes the basering to the differential algebra for computations
27    diffAlgebraGens();              defines the differential forms dx_1,...,dx_n
28    diffAlgebraUnivDerIdeal(ideal); computes the image of an ideal under the universal derivation
29    diffAlgebraChangeOrd(list);     returns a ring with the structure of the differential algebra but changed monomial ordering
30    diffAlgebraListGen(int);        returns a list of the generators of the differential algebra or of a graded part of it
31    difformFromPoly(poly);          constructs differential forms of degree 0 from polynomials
32    difformCoef(difform);           computes the representation as an linear combination of the generators
33    difformGenToString(difform);    casts a generator of the differential algebra to a string
34    difformHomogDecomp(df);         list of differential forms: homogeneous decomposition
35    difformToString(difform);       casts a differential form to a string
36    difformPrint(difform);          prints differential forms
37    difformIsGen(difform);          decides, whether a given differential form is a generator of the differential algebra
38    difformAdd(difform,difform);        adds two differential forms
39    difformSub(difform,difform);        subtracts one differential form from the other
40    difformNeg(difform);                returns the negative of a differential form
41    difformMul(difform,difform);        multiplies two differential forms
42    difformDiv(difform,difform);        computes the quotient of two differential forms
43    difformEqu(difform,difform);        compares two differential forms
44    difformNeq(difform,difform);        returns the negation of comparing two differential forms
45    difformIsBigger(difform,difform);   tests if a given differential form is greater than another one
46    difformIsSmaller(difform,difform);  tests if a given differential form is smaller than another one
47    difformDeg(difform);            returns the degree of a given differential form
48    difformIsHomog(difform);        checks if the given differential form is homogeneous
49    difformIsHomogDeg(difform,int); checks if the given differential form is homogeneous of given degree
50    difformListCont(list,difform);  checks if a given differential form is in a given list
51    difformListSort(list);          sorts lists of differential forms and special lists of lists
52    difformUnivDer(difform);    computes the image of an polynomial under the universal derivation
53    difformDiff(difform);       computes the image of an differential form under the differential
54    derivationFromList(list);       constructs a derivation from a given list
55    derivationCheckList(list);      checks the form of a given structure list for a derivation
56    derivationFromPoly(poly);       creates a derivation from a polynomial
57    derivationConstructor(def);     constructs a derivation from arbitrary input
58    derivationToString(derivation); casts a derivation to a string
59    derivationPrint(derivation);    prints a derivation
60    derivationAdd(derivation,derivation);   computes the sum of two derivations
61    derivationSub(derivation,derivation);   subtracts two derivations
62    derivationNeg(derivation);              negates a given derivation
63    derivationMul(derivation,derivation);   multiplies two derivations componentwise
64    derivationEqu(derivation,derivation);   compares two derivations
65    derivationNeq(derivation,derivation);   returns the negation of comparing two derivations
66    derivationEval(derivation,difform);     evaluates a derivation at a given differential form of degree 1
67    derivationContractionGen(derivation,difform);   computes the contraction and applies it to a generator
68    derivationContraction(derivation,difform);      computes the contraction and applies it to a differential form
69    derivationLie(derivation,difform);              returns the Lie-derivative applied to a differential form
70
71KEYWORDS: differential forms;differentials;differential algebra
72";
73////////////////////////////////////////////////////////////////////////////////////////////////
74////////////////////////////////////////////////////////////////////////////////////////////////
75
76
77////////////////////////////////////////////////////////////////////////////////////////////////
78////////////////////////////////////////////////////////////////////////////////////////////////
79//                                  Initialization of library                                 //
80////////////////////////////////////////////////////////////////////////////////////////////////
81////////////////////////////////////////////////////////////////////////////////////////////////
82
83
84static proc mod_init()
85{
86        // Type of differential forms:
87        // These are considered as elements (polynomials) in the differential algebra
88    // NOTE: the polynomials 'form' are not visible in the basering - only in the differential algebra
89        newstruct("difform","poly form");
90
91    // Type of derivations - these are maps: Omega_R^1 -> R
92    // The maps are uniquely determined by the images of the R-generators of Omega_R^1: dx_1,...,dx_n
93    // A derivation consists of a list of two lists: genIm[1][i] is a generator and genIm[2][i] the image of it
94    // The list of generators is always ordered by the ordering given on the differential algebra
95    newstruct("derivation","list genIm");
96
97        // Overloads for difform
98        system("install", "difform", "=", difformFromPoly, 1);
99        system("install", "difform", "print", difformPrint, 1);
100
101        system("install", "difform", "+", difformAdd, 2);
102        system("install", "difform", "-", difformSub, 2);
103        system("install", "difform", "-", difformNeg, 1);
104        system("install", "difform", "*", difformMul, 2);
105    system("install", "difform", "/", difformDiv, 2);
106        system("install", "difform", "==", difformEqu, 2);
107        system("install", "difform", "<>", difformNeq, 2);
108    system("install", "difform", ">", difformIsBigger,2);
109    system("install", "difform", "<", difformIsSmaller,2);
110
111        system("install", "difform", "deg", difformDeg, 1);
112    system("install", "difform", "homog", difformIsHomog, 1);
113
114    // Overloads for derivation
115    system("install", "derivation", "=", derivationConstructor, 1);
116    system("install", "derivation", "print", derivationPrint, 1);
117
118    system("install", "derivation", "+", derivationAdd, 2);
119    system("install", "derivation", "-", derivationSub, 2);
120    system("install", "derivation", "-", derivationNeg, 1);
121    system("install", "derivation", "*", derivationMul, 2);
122    system("install", "derivation", "==", derivationEqu, 2);
123    system("install", "derivation", "<>", derivationNeq, 2);
124    system("install", "derivation", "(", derivationEval, 2);
125
126    system("install", "derivation", "diff", derivationLie, 2);
127
128    // Libraries needed
129    LIB "inout.lib";
130}
131
132
133////////////////////////////////////////////////////////////////////////////////////////////////
134////////////////////////////////////////////////////////////////////////////////////////////////
135//                            Construction of differential algebra                            //
136////////////////////////////////////////////////////////////////////////////////////////////////
137////////////////////////////////////////////////////////////////////////////////////////////////
138
139
140// TODO: check if qringNF option is set - if yes: turn off and set afterwards on
141proc diffAlgebra()
142"USAGE:         diffAlgebra();
143SIDE EFFECTS:   If R is the basering, the differential algebra is constructed with name Omega_R
144                and the differential forms dx_1,...,dx_n are available. The name of the differential
145                algebra is stored in the attribute attrib(R,"diffAlgebra").
146NOTE:           - computations with differential forms need the structure of the differential algebra,
147                so this procedure should be executed first.
148                - the variable names 'd' or 'D' should be avoided.
149                - the procedure also works for quotient rings
150KEYWORDS:       differential algebra; differential forms; differentials
151SEE ALSO:       diffAlgebraStructure, diffAlgebraGens, diffAlgebraUnivDerIdeal
152EXAMPLE:        example diffAlgebra; shows an example"
153{
154
155    // Build the differential algebra and store its name as an attribute
156    string diffAlg_name = diffAlgebraStructure();
157    attrib(basering,"diffAlgebra",diffAlg_name);
158
159    // Construct the differential forms dx_1,...,dx_n over the basering
160    diffAlgebraGens();
161
162    // Info for User
163    list vars_ = ringlist(basering)[2];
164    int n = size(vars_);
165    int i;
166    string basic_forms;
167
168    basic_forms = "d" + vars_[1];
169    for(i = 2; i <= n; i++){
170        basic_forms = basic_forms + ", d" + vars_[i];
171    }
172
173    string info_text = "// The differential algebra " + attrib(basering,"diffAlgebra") + " was constructed and the differential forms " + basic_forms + " are available.";
174    print(info_text);
175    return();
176
177}
178example
179{
180"EXAMPLE:"; echo = 2;
181///////////////////////////////////////////////////////////////
182// Example for a differential algebra over a polynomial ring //
183///////////////////////////////////////////////////////////////
184
185ring R = 0,(a,b,c),ds;
186diffAlgebra();
187setring Omega_R;
188
189// The differential algebra is given by:
190basering;
191
192kill R,Omega_R,da,db,dc;
193
194/////////////////////////////////////////////////////////////
195// Example for a differential algebra over a quotient ring //
196/////////////////////////////////////////////////////////////
197
198ring R = 0,(x,y,z),lp;
199ideal I = x+y+z,xyz;
200qring S = std(I);
201diffAlgebra();
202setring Omega_S;
203
204// The differential algebra is given by:
205basering;
206
207kill Omega_S,dx,dy,dz;
208}
209
210
211////////////////////////////////////////////////////////////////////////////////////////////////
212
213
214proc diffAlgebraStructure()
215"USAGE:     diffAlgebraStructure();
216RETURN:     the structure of the differential algebra
217REMARKS:    The differential algebra is constructed as non-commutative ring with
218            additional variables Dx_1,...,Dx_n and 'exterior' relations between them.
219            In the case, that the basering is a quotient ring, the defining ideal and its image
220            under the universal derivation are added as relations.
221NOTE:       the monomial ordering of the basering is preserved in the differential algebra
222KEYWORDS:   differential algebra
223SEE ALSO:   diffAlgebra, diffAlgebraGens, diffAlgebraUnivDerIdeal"
224{
225
226    string basering_name = nameof(basering);
227        list base_list = ringlist(basering);
228    def R_old = basering;
229    ideal quot_ideal = base_list[4];
230
231        // Add Dx_1,...,Dx_n as first variables
232        list ext_var = base_list[2];
233        int n = size(ext_var);
234        int i;
235
236        for(i = 1; i <= n; i++){
237        ext_var[n+i] = ext_var[i];
238                ext_var[i] = "D" + ext_var[n+i];
239        }
240
241        base_list[2] = ext_var;
242
243    // Preserve the monomial order of the basering
244    // Add a new first block for the variables dx_i with dp ordering
245    intvec weight_vec = 1:n;
246    base_list[3] = list(list("dp",weight_vec)) + base_list[3];
247
248        // Add relations x_i*x_j = x_j*x_i and dx_i*dx_j = -dx_j*dx_i
249        int k = 2*n;
250        matrix C[k][k];
251        matrix D[k][k];
252        int j;
253
254        // Generate strictly upper triangular matrix describing the relations
255        for(i = 1; i <= k; i++){
256            for(j = i+1; j <= k ; j++){
257            if(j <= n){
258                        C[i,j] = -1;
259            }else{
260                C[i,j] = 1;
261            }
262                }
263        }
264
265    base_list[4] = ideal(0);
266        base_list[5] = C;
267        base_list[6] = D;
268
269        // Pass to non-commutative ring with extra variables and relations
270        ring R_intermediate = ring(base_list);
271
272        // Add relations Dx_i*Dx_i = 0 via generating a quotient ring
273        ideal REL;
274        for(i = 1; i <= n; i++){
275                REL[i] = var(i)*var(i);
276        }
277
278        // Build the differential algebra for the polynomial ring - the free module
279    qring diffAlg_poly = twostd(REL);
280
281    // Need the relations describing the differential algebra if R is a quotient ring
282    ideal quot_ideal = imap(R_old,quot_ideal);
283
284    if(quot_ideal != 0){
285
286        // Compute the universal derivation of the generators of the ideal
287        quot_ideal = quot_ideal + diffAlgebraUnivDerIdeal(quot_ideal);
288
289        // Add the additional relations, generate the differential algebra with name Omega_R and export it
290        string diffAlg_name = "Omega_" + basering_name;
291            execute("qring " + diffAlg_name + " = twostd(quot_ideal);");
292        execute("exportto(Top," + diffAlg_name + ");");
293
294        return(diffAlg_name);
295    }
296
297    // Give the differential algebra the name Omega_basering and export it
298    string diffAlg_name = "Omega_" + basering_name;
299        execute("ring " + diffAlg_name + " = diffAlg_poly;");
300    execute("exportto(Top," + diffAlg_name + ");");
301
302    return(diffAlg_name);
303
304}
305
306
307////////////////////////////////////////////////////////////////////////////////////////////////
308
309
310proc diffAlgebraCheck()
311"USAGE:         diffAlgebraCheck();
312SIDE EFFECTS:   Checks if the basering has a differential algebra and aborts with an error if this is not the case
313REMARKS:        The procedure checks if the name in the attribute attrib(basering,"diffAlgebra") is not empty. This
314                is the case if the procedure diffAlgebra was executed first.
315NOTE:           whenever computations with differential forms are done, it should be checked if the differential
316                algebra was already generated since differential forms are polynomials in the differential algebra
317KEYWORDS:       differential algebra
318SEE ALSO:       diffAlgebraSwitch"
319{
320    string diffAlg_name = attrib(basering,"diffAlgebra");
321    if(size(diffAlg_name) == 0){
322        ERROR("Ring does not have a differential algebra!");
323    }
324}
325
326
327////////////////////////////////////////////////////////////////////////////////////////////////
328
329
330proc diffAlgebraSwitch()
331"USAGE:         diffAlgebraSwitch();
332ASSUME:         The differential algebra was already constructed.
333SIDE EFFECTS:   Changes the ring: from the basering to the differential algebra.
334NOTE:           whenever computations with differential forms are done, the ring must be changed to the differential
335                algebra since differential forms are polynomials there. But first it should be checked if the algebra
336                is actually available: so before executing diffAlgebraSwitch there should always be an preceding diffAlgebraCheck
337KEYWORDS:       differential algebra
338SEE ALSO:       diffAlgebraCheck"
339{
340
341    string diffAlg_name = attrib(basering,"diffAlgebra");
342    execute("setring " + diffAlg_name);
343    execute("keepring " + diffAlg_name);
344
345}
346
347
348////////////////////////////////////////////////////////////////////////////////////////////////
349
350
351proc diffAlgebraGens()
352"USAGE:         diffAlgebraGens();
353SIDE EFFECTS:   The differential forms dx_1,...,dx_n are constructed.
354KEYWORDS:       differential algebra; generator
355SEE ALSO:       diffAlgebra, diffAlgebraStructure, diffAlgebraUnivDerIdeal"
356{
357
358    diffAlgebraSwitch();
359
360    list ext_var = ringlist(basering)[2];
361    int n = size(ext_var) div 2;
362    int i;
363    string dif_cons;
364
365    for(i = 1; i <= n; i++){
366        dif_cons = "difform d" + ext_var[i+n] + ";";
367        dif_cons = dif_cons + "d" + ext_var[i+n] + ".form = " + ext_var[i] + ";";
368        dif_cons = dif_cons + " exportto(Top," + "d" + ext_var[i+n] + ")" + ";";
369        execute(dif_cons);
370    }
371}
372
373
374////////////////////////////////////////////////////////////////////////////////////////////////
375
376
377proc diffAlgebraUnivDerIdeal(ideal I)
378"USAGE:     diffAlgebraUnivDerIdeal(I); I ideal
379ASSUME:     current basering is the differential algebra of a polynomial ring
380            and I is lifted from the polynomial ring
381RETURN:     the image of I under the universal derivation
382REMARK:     The procedure computes the universal derivation of every generator of the ideal.
383NOTE:       for differential forms use the procedure difformUnivDer or difformDiff
384KEYWORDS:   differential algebra; universal derivation
385SEE ALSO:   diffAlgebra, diffAlgebraStructure, diffAlgebraGens"
386{
387
388    int n = size(ringlist(basering)[2]) div 2;
389    int k = size(I);
390    int i,j;
391    ideal d_I;
392
393    for(j = 1; j <= k; j++){
394        d_I[j] = 0;
395        for(i = 1; i <= n; i++){
396            d_I[j] = d_I[j] + diff(I[j],var(i+n))*var(i);
397        }
398    }
399
400    return(d_I);
401
402}
403
404
405////////////////////////////////////////////////////////////////////////////////////////////////
406
407
408proc diffAlgebraChangeOrd(list #)
409"USAGE:     diffAlgebraChangeOrd(#); # list
410ASSUME:     the current basering is the differential algebra
411RETURN:     the differential algebra with changed monomial ordering
412NOTE:       - an ordering is defined via the following pattern:
413                - #[i] = 'gen' defines the ordering on the generators dx_i
414                    - #[i+1] must then be a valid monomial ordering as string
415                    - #[i+2] an optional weight vector
416                - #[i] = 'ringvar' defines the ordering on the ringvariables
417                    - #[i+1] must then be a valid monomial ordering as string
418                    - #[i+2] an optional weight vector
419            - only use for interior computations
420            - differential forms are polynomials in the differential algebra - not in the returned ring
421            - do not define differential forms as polynomials in the returned ring since this is another data-ring
422            - an error occurs if:   - no valid monomial ordering is given
423                                    - no weight vector is given but a weighted monomial ordering
424                                    - a given weight vector has wrong dimension
425            - weight vectors are ignored if the given ordering is not weighted
426KEYWORDS:   ordering
427SEE ALSO:   difformListSort, difformIsBigger, difformIsSmaller"
428{
429
430    int n = size(#);
431    int k = size(ringlist(basering)[2]) div 2;
432    int i;
433    string gen_ord = "";
434    string ringvar_ord = "";
435
436    // Get information from input
437    for(i = 1; i <= n; i++){
438        if(typeof(#[i]) == "string"){
439
440            if(#[i] == "gen" && typeof(#[i+1]) == "string"){
441                gen_ord = #[i+1];
442                if(typeof(#[i+2]) == "intvec"){
443                    intvec gen_weight = #[i+2];
444                }
445            }
446
447            if(#[i] == "ringvar" && typeof(#[i+1]) == "string"){
448                ringvar_ord = #[i+1];
449                if(typeof(#[i+2]) == "intvec"){
450                    intvec ringvar_weight = #[i+2];
451                }
452            }
453        }
454    }
455
456    // Check input for consistency
457    // Generator ordering must be a valid monomial ordering
458    if(gen_ord != "" && gen_ord != "lp" && gen_ord != "rp" && gen_ord != "dp" && gen_ord != "Dp" && gen_ord != "wp" && gen_ord != "Wp"){
459        if(gen_ord != "ls" && gen_ord != "ds" && gen_ord != "Ds" && gen_ord != "ws" && gen_ord != "Ws"){
460            ERROR("Not a valid ordering!");
461        }
462    }
463
464    // Ringvariable ordering must be a valid monomial ordering
465    if(ringvar_ord != "" && ringvar_ord != "lp" && ringvar_ord != "rp" && ringvar_ord != "dp" && ringvar_ord != "Dp" && ringvar_ord != "wp" && ringvar_ord != "Wp"){
466        if(ringvar_ord != "ls" && ringvar_ord != "ds" && ringvar_ord != "Ds" && ringvar_ord != "ws" && ringvar_ord != "Ws"){
467            ERROR("Not a valid ordering!");
468        }
469    }
470
471    // If the generator ordering is a weighted monomial ordering, a weight-vector is needed
472    if(gen_ord == "wp" || gen_ord == "Wp" || gen_ord == "ws" || gen_ord == "Ws"){
473        if(!defined(gen_weight)){
474            ERROR("No weight vector given!");
475        }
476
477        if(size(gen_weight) != k){
478            ERROR("Weight vector has wrong size!");
479        }
480    }else{
481    // If a weight vector is given although the monomial ordering is not weighted
482        if(defined(gen_weight)){
483            kill gen_weight;
484        }
485    }
486
487    // If the ordering for the ring variables is a weighted monmial ordering, a weight-vector is needed
488    if(ringvar_ord == "wp" || ringvar_ord == "Wp" || ringvar_ord == "ws" || ringvar_ord == "Ws"){
489        if(!defined(ringvar_weight)){
490            ERROR("No weight vector given!");
491        }
492
493        if(size(ringvar_weight) != k){
494            ERROR("Weight vector has wrong size!");
495        }
496    }else{
497    // If a weight vector is given although the monomial ordering is not weighted
498        if(defined(ringvar_weight)){
499            kill ringvar_weight;
500        }
501    }
502
503    list L_diff_Alg = ringlist(basering);
504    n = size(L_diff_Alg[3]);
505
506    // Change ordering of generators
507    if(gen_ord != ""){
508        L_diff_Alg[3][1][1] = gen_ord;
509        if(defined(gen_weight)){
510            L_diff_Alg[3][1][2] = gen_weight;
511        }
512    }
513
514    // Change the ordering of the ringvariables
515    if(ringvar_ord != ""){
516        list L;
517        L[1] = L_diff_Alg[3][1];
518
519        L[2] = list();
520        L[2][1] = ringvar_ord;
521        if(defined(ringvar_weight)){
522            L[2][2] = ringvar_weight;
523        }else{
524            L[2][2] = 1:k;
525        }
526
527        L_diff_Alg[3] = L;
528    }
529
530    def T = ring(L_diff_Alg);
531    return(T);
532
533}
534
535
536////////////////////////////////////////////////////////////////////////////////////////////////
537
538
539proc diffAlgebraListGen(list #)
540"USAGE: diffAlgebraListGen(#); # list
541RETURN:     - a list of generetors of the differential algebra as module over the basering
542            - a list of generators of a graded part of the differential algebra
543REMARKS:    In order to find all generators, they are counted 'binary': The generators are in
544            1:1 - correspondance to the dual number representations of 1 up to (2^n-1)
545NOTE:       - if all generators of the differential algebra are needed, apply the
546            procedure without input
547            - if the generator(s) of a graded part are needed, apply the procedure with
548            an integer which specifies the wanted degree
549            - the list of generators is sorted with respect to the monomial ordering on the
550            differential algebra
551KEYWORDS:   generators; graded
552SEE ALSO:   diffAlgebraIntToDual
553EXAMPLE:    example diffAlgebraListGen; shows an example"
554{
555
556    diffAlgebraCheck();
557
558    int n = size(ringlist(basering)[2]);
559    int i,k,j;
560    int degr = -1;
561    list var_list;
562    list GEN_list;
563    difform current_var;
564    difform current_gen;
565
566    // Get optional degree
567    if(size(#) > 0){
568        if(typeof(#[1]) == "int"){
569            degr = #[1];
570        }
571    }
572
573    // Build the list of all dx_i
574    def R_old = basering;
575    diffAlgebraSwitch();
576
577    for(i = 1; i <= n; i++){
578        current_var.form = var(i);
579        var_list[i] = current_var;
580    }
581
582    setring R_old;
583
584    // Find all generators (of given degree)
585    list dual_i;
586    for(i = 1; i < 2^n; i++){
587        // Compute dual number representation
588        dual_i = diffAlgebraIntToDual(i);
589        k = size(dual_i);
590        current_gen = 1;
591
592        // Convert dual number to generator
593        for(j = 1; j <= k; j++){
594            if(dual_i[j] != 0){
595                current_gen = current_gen*var_list[j];
596            }
597        }
598
599        // Add generator if it has the given degree or degree was not chosen
600        if(degr == -1 || difformDeg(current_gen) == degr){
601            GEN_list = GEN_list + list(current_gen);
602        }
603    }
604
605    // Add generator 1
606    if(degr == 0 || degr == -1){
607        difform gen_one = 1;
608        GEN_list = list(gen_one) + GEN_list;
609    }
610
611    return(difformListSort(GEN_list));
612
613}
614example
615{
616"EXAMPLE:"; echo = 2;
617ring R = 11,(x,y,z),dp;
618diffAlgebra();
619
620////////////////////////////////////////////
621// Generators of the differential algebra //
622////////////////////////////////////////////
623diffAlgebraListGen();
624
625//////////////////////////////////////////
626// Generators of the second graded part //
627//////////////////////////////////////////
628diffAlgebraListGen(2);
629
630kill Omega_R,dx,dy,dz;
631}
632
633
634////////////////////////////////////////////////////////////////////////////////////////////////
635
636
637static proc diffAlgebraIntToDual(int l)
638"USAGE:     diffAlgebraIntToDual(l); l int
639RETURN:     the dual number representation of l as a list
640NOTE:       the LSBF (least significant bit first) representation is computed
641KEYWORDS:   dual; int
642SEE ALSO:   diffAlgebraListGen"
643{
644
645    list dual_number;
646
647    while(l div 2 != 0){
648        dual_number = dual_number + list(l mod 2);
649        l = l div 2;
650    }
651
652    dual_number = dual_number + list(l mod 2);
653
654    return(dual_number);
655
656}
657
658
659////////////////////////////////////////////////////////////////////////////////////////////////
660////////////////////////////////////////////////////////////////////////////////////////////////
661//                                Procedures for type difform                                 //
662////////////////////////////////////////////////////////////////////////////////////////////////
663////////////////////////////////////////////////////////////////////////////////////////////////
664
665
666////////////////////////////////////////////////////////////////////////////////////////////////
667//----------------------------------- Structural procedures ----------------------------------//
668////////////////////////////////////////////////////////////////////////////////////////////////
669
670
671proc difformFromPoly(poly f)
672"USAGE:     difform df = f; f poly
673RETURN:     the differential form of degree 0 defined by f
674REMARK:     The given polynomial gets lifted to the differential algebra
675            and the differential form is defined there.
676KEYWORDS:   constructor; differential
677EXAMPLE:    example difformFromPoly; shows an example"
678{
679
680    diffAlgebraCheck();
681    def R_old = basering;
682    diffAlgebraSwitch();
683
684    poly g = imap(R_old,f);
685    difform df;
686    df.form = g;
687
688    return(df);
689
690}
691example
692{
693"EXAMPLE:"; echo = 2;
694ring R = 0,(x,y,z),ds;
695diffAlgebra();
696
697////////////////////////////////////////
698// Construction of differential forms //
699////////////////////////////////////////
700
701poly f = 3x3z*(y4-y5) + 2;
702difform df = f;
703df;
704
705// For the construction of more general differential forms,
706// the constructor difformFromPoly is used implicitely:
707
708difform dg = 3*x*dx - y*dy + dx*dy*dz + 1;
709dg;
710
711kill Omega_R,df,dg,dx,dy,dz;
712}
713
714
715////////////////////////////////////////////////////////////////////////////////////////////////
716
717
718proc difformCoef(difform df)
719"USAGE:     difformCoef(df); df difform
720RETURN:     list of lists of differential forms and polynomials:
721            - the first entry is a generator of the differential algebra which appears in df
722            - the second entry is the corresponding coefficient
723REMARKS:    Via the procedure coef, the coefficients are found - therefore the ring has to be changed to the
724            differential algebra. After that, the coefficients have to be mapped back to the original ring.
725NOTE:       the returned list can be sorted with the procedure difformListSort and the optional string 'Llist'
726KEYWORDS:   decomposition; generators; coefficients
727EXAMPLE:    example difformCoef; shows an example"
728{
729
730    diffAlgebraCheck();
731    def R_old = basering;
732    diffAlgebraSwitch();
733    def diff_Alg = basering;
734
735    poly f = df.form;
736    int n = size(ringlist(basering)[2]) div 2;
737    int i;
738
739        // Build the wedge product of all differential forms dx_i
740        poly wedge_mon = 1;
741        for(i = 1; i <= n; i++){
742                wedge_mon = wedge_mon*var(i);
743        }
744
745        // Find the coefficients of the generators
746    matrix df_coefs = coef(f,wedge_mon);
747    int k = ncols(df_coefs);
748
749    // Store representation in a list
750    poly coeff_above;
751    setring R_old;
752    difform current_gen;
753    poly coeff;
754    list repr;
755
756    for(i = 1;i <= k;i++){
757        repr[i] = list();
758        setring diff_Alg;
759
760        // Generators as differential forms
761        current_gen.form = df_coefs[1,i];
762
763        // Coefficients are polynomials in the basering
764        coeff_above = df_coefs[2,i];
765        setring R_old;
766        coeff = imap(diff_Alg,coeff_above);
767
768        repr[i][1] = current_gen;
769        repr[i][2] = coeff;
770    }
771
772    // Return representation
773    return(repr);
774
775}
776example
777{
778"EXAMPLE:"; echo = 2;
779ring R = 0,(x,y,z),lp;
780diffAlgebra();
781
782difform df = 3*x25*dx - y*dx*dy + 12*dx*dy*dz - dz*dy + 3 + 12*x*dx + 24*(y4-y5) + dx*dy*x3*dz + dz - dy*dx + dz*x2 + z5*y*dy;
783
784///////////////////////////////
785// Unsorted Coefficient List //
786///////////////////////////////
787list L_1 = difformCoef(df);
788L_1;
789
790/////////////////////////////
791// Sorted Coefficient List //
792/////////////////////////////
793L_1 = difformListSort(L_1,"Llist","gen","ds");
794L_1;
795
796kill Omega_R,df,dx,dy,dz,L_1;
797}
798
799
800////////////////////////////////////////////////////////////////////////////////////////////////
801
802
803proc difformGenToString(difform df)
804"USAGE:     difformGenToString(df); df difform
805RETURN:     the differential form df as a string - but with unsorted coefficients
806NOTE:       - this is only used to print generators
807            - the procedure replaces the 'D' from the variables of the differential algebra
808            by an 'd'
809KEYWORDS:   string; print; generators
810SEE ALSO:   difformToString"
811{
812
813    diffAlgebraSwitch();
814    string df_out_un = string(df.form);
815    list vars_ = ringlist(basering)[2];
816    int n = size(vars_) div 2;
817    int i,j;
818
819    // Replace the Dx_i in the string with the dx_i
820    for(i = 1; i <= n; i++){
821        j = find(df_out_un,string(vars_[i]));
822
823        while(j!=0){
824            df_out_un[j] = "d";
825            j = find(df_out_un,vars_[i]);
826        }
827    }
828
829    return(df_out_un);
830
831}
832
833
834////////////////////////////////////////////////////////////////////////////////////////////////
835
836
837// TODO: check optionIsSet("qringNF") - ADD ring.lib !!! and reduce by hand
838proc difformToString(difform df, list #)
839"USAGE:     difformToString(df,#); df difform,# list
840RETURN:     df as a string, sorted by a given ordering on the generators (standard: the ordering chosen for the differential algebra)
841REMARKS:    The differential form is decomposed via difformCoef, the coefficient list is sorted
842            and then the string is built as concatenation of coefficients and generators
843NOTE:       to get a string, respecting a certain monomial ordering on the generators, use:
844                - #[1] = 'gen'
845                - #[2]: a monomial ordering as string
846                - #[3]: an optional weight vector
847KEYWORDS:   string; print
848SEE ALSO:   difformPrint, difformGenToString
849EXAMPLE:    example difformToString; shows an example"
850{
851
852    // Get the coefficients
853    list repr = difformCoef(df);
854
855    // Get the optional ordering on the generators
856    string gen_ord = "";
857    int n = size(#);
858    int i;
859
860    for(i = 1; i <= n; i++){
861        if(typeof(#[i]) == "string"){
862            if(#[i] == "gen" && typeof(#[i+1]) == "string"){
863                gen_ord = #[i+1];
864                if(typeof(#[i+2]) == "intvec"){
865                    intvec gen_weight = #[i+2];
866                }
867            }
868        }
869    }
870
871    // Sort the generator/coefficients by the chosen ordering
872    if(gen_ord != ""){
873        if(defined(gen_weight)){
874            repr = difformListSort(repr,"Llist","gen",gen_ord,gen_weight);
875        }else{
876            repr = difformListSort(repr,"Llist","gen",gen_ord);
877        }
878    }else{
879        repr = difformListSort(repr,"Llist");
880    }
881
882    // Build the string
883    n = size(repr);
884    string df_out;
885
886    difform df_gen;
887    string df_gen_str;
888    poly df_coef;
889    string df_coef_str;
890
891    for(i = n; i >= 1; i--){
892        df_gen = repr[i][1];
893        df_gen_str = difformGenToString(df_gen);
894        df_coef = repr[i][2];
895        df_coef_str = string(df_coef);
896
897        // Check the coefficients and generators
898        while(1){
899            // Special cases without brackets:
900
901            // Generator one
902            if(df_gen_str == "1"){df_out = df_out + df_coef_str; break;}
903
904            // Generator not one - coefficient is one
905            if(df_gen_str != "1" && df_coef == 1){df_out = df_out + df_gen_str; break;}
906
907            // Generator not one - coefficient not one - coefficient has one term - term has no sign
908            if(df_gen_str != "1" && df_coef != 1 && size(df_coef) == 1 && df_coef_str[1] != "-"){df_out = df_out +  df_coef_str + "*" + df_gen_str; break;}
909
910            // Case, where brackets are needed:
911            df_out = df_out + "(" + df_coef_str + ")*" + df_gen_str; break;
912        }
913
914        // Add a plus sign
915        if(i > 1){
916            df_out = df_out + "+";
917        }
918    }
919
920        return(df_out);
921
922}
923example
924{
925"EXAMPLE:"; echo = 2;
926ring R = 0,(x,y,z,a,b),ds;
927diffAlgebra();
928
929difform df = 3*x*dx -2*db + 24*a*dy - y*dx*dy*db + 12*dx*dy*dz - dz*dy*da*db + 3 + 12*x*dx - 1/77*da*dx;
930
931//////////////////////////////////////////////////////////////////////////////////
932// String sorted with respect to the monomial order on the differential algebra //
933//////////////////////////////////////////////////////////////////////////////////
934string df_str = difformToString(df);
935print(df_str);
936
937/////////////////////////////////////////////////////////
938// String sorted with respect to the weighted order wp //
939/////////////////////////////////////////////////////////
940df_str = difformToString(df,"gen","wp",intvec(-1,-1,-1,1,1));
941print(df_str);
942
943kill Omega_R,df,df_str,dx,dy,dz,da,db;
944}
945
946
947////////////////////////////////////////////////////////////////////////////////////////////////
948
949
950proc difformPrint(difform df)
951"USAGE:         df; df difform
952SIDE EFFECTS:   prints the differential form
953REMARKS:        Uses the procedure difformToString with a ds-ordering on the generators
954KEYWORDS:       print; string
955SEE ALSO:       difformToString, difformGenToString
956EXAMPLE:        example difformPrint; shows an example"
957{
958
959    // Print in ds-order on the generators
960        print(difformToString(df,"gen","ds"));
961    return();
962
963}
964example
965{
966"EXAMPLE:"; echo = 2;
967ring R = 0,(x,y,z),ds;
968diffAlgebra();
969
970//////////////////////////
971// Application of Print //
972//////////////////////////
973
974difform df = 3*x*dx - y*dx*dy + 12*dx*dy*dz - dz*dy + 3 + 12*x*dx;
975df;
976
977kill Omega_R,df,dx,dy,dz;
978}
979
980
981////////////////////////////////////////////////////////////////////////////////////////////////
982
983
984proc difformIsGen(difform df)
985"USAGE:      difformIsGen(df); df difform
986RETURN:     1, if df is a generator of the differential algebra - 0, otherwise
987REMARKS:    Uses the procedure difformCoef and tests for a single coefficient which is one
988KEYWORDS:   generator
989SEE ALSO:   difformCoef
990EXAMPLE:    example difformIsGen; shows an example
991"
992{
993
994    diffAlgebraCheck();
995    list df_gen_repr = difformCoef(df);
996    int n = size(df_gen_repr);
997
998    if(n == 1 && df_gen_repr[1][2] == 1){
999        return(1);
1000    }
1001
1002    return(0);
1003
1004}
1005example
1006{
1007"EXAMPLE:"; echo = 2;
1008ring R = 0,(x,y,z,a,b,c),lp;
1009diffAlgebra();
1010
1011////////////////
1012// Generators //
1013////////////////
1014difformIsGen(1);
1015difformIsGen(dx);
1016difformIsGen(da*dc);
1017difformIsGen(dy*da*db);
1018difformIsGen(-da*dz);
1019
1020///////////////////
1021// No generators //
1022///////////////////
1023difformIsGen(-1);
1024difformIsGen(-dx);
1025difformIsGen(dc*da);
1026difformIsGen(dy*db*da);
1027difformIsGen(dx*dz*dy);
1028
1029kill Omega_R,dx,dy,dz,da,db,dc;
1030}
1031
1032
1033////////////////////////////////////////////////////////////////////////////////////////////////
1034//------------------------------ Basic computational procedures ------------------------------//
1035////////////////////////////////////////////////////////////////////////////////////////////////
1036
1037
1038// TODO: update example
1039proc difformAdd(difform df, difform dg)
1040"USAGE:     df+dg; df,dg difform
1041RETURN:     the sum of the differential forms as differential form
1042KEYWORDS:   add; sum
1043SEE ALSO:   difformSub
1044EXAMPLE:    example difformAdd; shows an example"
1045{
1046
1047    diffAlgebraCheck();
1048    diffAlgebraSwitch();
1049
1050    difform dsum;
1051    poly sum_form = df.form + dg.form;
1052    dsum.form = sum_form;
1053
1054    return(dsum);
1055
1056}
1057example
1058{
1059"EXAMPLE:"; echo = 2;
1060ring R = 0,(x,y,z),ds;
1061diffAlgebra();
1062
1063////////////////////////////////////
1064// Addition of differential forms //
1065////////////////////////////////////
1066
1067difform df = dx + 4*dy - dz*dx + 4 + 3*dx*dy + 4*dz;
1068difform dg = dx + dy + 27*dz*dy;
1069df+dg;
1070
1071////////////////////////////////////////////////////
1072// Addition of polynomials and differential forms //
1073////////////////////////////////////////////////////
1074
1075df + x2y2z2;
107612 + dg;
1077
1078kill Omega_R,df,dg,dx,dy,dz;
1079}
1080
1081
1082////////////////////////////////////////////////////////////////////////////////////////////////
1083
1084
1085proc difformSub(difform df, difform dg)
1086"USAGE:     df-dg; df,dg difform
1087RETURN:     the difference of the differential forms as differential form
1088KEYWORDS:   minus; difference
1089SEE ALSO:   difformAdd, difformNeg
1090EXAMPLE:    example difformSub; shows an example"
1091{
1092
1093        diffAlgebraCheck();
1094    diffAlgebraSwitch();
1095
1096    difform dsub;
1097    poly sub_form = df.form - dg.form;
1098    dsub.form = sub_form;
1099
1100    return(dsub);
1101
1102}
1103example
1104{
1105"EXAMPLE:"; echo = 2;
1106ring R = 0,(x,y,z),ds;
1107diffAlgebra();
1108
1109///////////////////////////////////////
1110// Subtraction of differential forms //
1111///////////////////////////////////////
1112
1113difform df = 5*dx*x2 - 7*dy*z - 2x2*dz - 3;
1114difform dg = dx - 8x*dz*dy;
1115df-dg;
1116
1117///////////////////////////////////////////////////////
1118// Subtraction of polynomials and differential forms //
1119///////////////////////////////////////////////////////
1120
1121df - 2x3;
11221 - dg;
1123
1124kill Omega_R,df,dg,dx,dy,dz;
1125}
1126
1127
1128////////////////////////////////////////////////////////////////////////////////////////////////
1129
1130
1131proc difformNeg(difform df)
1132"USAGE:     -df; df difform
1133RETURN:     the negation of the differential form
1134KEYWORDS:   minus; negation
1135SEE ALSO:   difformSub
1136EXAMPLE:    example difformNeg; shows an example"
1137{
1138
1139        diffAlgebraCheck();
1140    diffAlgebraSwitch();
1141
1142    difform dneg;
1143    poly neg_form = -df.form;
1144    dneg.form = neg_form;
1145
1146    return(dneg);
1147
1148}
1149example
1150{
1151"EXAMPLE:"; echo = 2;
1152ring R = 0,(x,y,z),ds;
1153diffAlgebra();
1154
1155/////////////////////////////////////
1156// Negation of a differential form //
1157/////////////////////////////////////
1158
1159difform df = 13*dx*dy + 2*dy*dz - 6*dx*dy*dz - 3;
1160-df;
1161
1162kill Omega_R,df,dx,dy,dz;
1163}
1164
1165
1166////////////////////////////////////////////////////////////////////////////////////////////////
1167
1168
1169proc difformMul(difform df, difform dg)
1170"USAGE:     df*dg; df,dg difform
1171RETURN:     the product of the differential forms as differential form
1172KEYWORDS:   multiplication; product
1173SEE ALSO:   difformDiv
1174EXAMPLE:    example difformMul; shows an example"
1175{
1176
1177        diffAlgebraCheck();
1178    diffAlgebraSwitch();
1179
1180    difform dmul;
1181    poly mul_form = df.form*dg.form;
1182    dmul.form = mul_form;
1183
1184    return(dmul);
1185
1186}
1187example
1188{
1189"EXAMPLE:"; echo = 2;
1190ring R = 0,(x,y,z),ds;
1191diffAlgebra();
1192
1193//////////////////////////////////////////
1194// Multiplication of differential forms //
1195//////////////////////////////////////////
1196
1197difform df = 13*dx*dy - 7*dy*dz - 6*dx*dy*dz;
1198difform dg = dx - 8x;
1199df*dg;
1200
1201/////////////////////////////////////////////////////////
1202// Multiplication of polynomials and differential forms //
1203/////////////////////////////////////////////////////////
1204
1205df*(y2-x);
120612*dg;
1207
1208kill Omega_R,df,dg,dx,dy,dz;
1209}
1210
1211
1212////////////////////////////////////////////////////////////////////////////////////////////////
1213
1214
1215proc difformDiv(difform df, difform dg)
1216"USAGE:     df/dg; df,dg difform
1217RETURN:     the quotient df/dg as differential form
1218KEYWORDS:   division
1219SEE ALSO:   difformMul
1220EXAMPLE:    example difformDiv; shows an example"
1221{
1222
1223    diffAlgebraCheck();
1224    diffAlgebraSwitch();
1225
1226    difform ddiv;
1227    poly div_form = df.form / dg.form;
1228    ddiv.form = div_form;
1229
1230    return(ddiv);
1231
1232}
1233example
1234{
1235"EXAMPLE:"; echo = 2;
1236ring R = 0,(x,y,z),lp;
1237diffAlgebra();
1238
1239/////////////////////////////////
1240// Divisions without remainder //
1241/////////////////////////////////
1242
1243dx / dx;
1244dx*dy*dz / dz;
1245(dx*x2 - yx2) / x2;
1246
1247//////////////////////////////
1248// Divisions with reaminder //
1249//////////////////////////////
1250
1251(dx + dx*dy + 1) / dx;
1252(x2*dx - x*dy) / (dx-dy);
1253
1254kill Omega_R,dx,dy,dz;
1255}
1256
1257
1258////////////////////////////////////////////////////////////////////////////////////////////////
1259
1260
1261proc difformEqu(difform df, difform dg)
1262"USAGE:     df == dg; df,dg difform
1263RETURN:     1, if df and dg are euqal - 0, otherwise
1264KEYWORDS:   compare; equal
1265SEE ALSO:   difformNeq
1266EXAMPLE:    example difformEqu; shows an example"
1267{
1268
1269        diffAlgebraCheck();
1270    diffAlgebraSwitch();
1271
1272    return(df.form == dg.form);
1273
1274}
1275example
1276{
1277"EXAMPLE:"; echo = 2;
1278ring R = 0,(x,y,z),ds;
1279diffAlgebra();
1280
1281/////////////////////////////////////////
1282// Applications of comparison operator //
1283/////////////////////////////////////////
1284
1285difform df = 3*dx - x8*dx*dy;
1286difform dg = 3 + x8*dy;
1287df == dg;
1288
1289dg = dg*dx;
1290df == dg;
1291
1292kill Omega_R,df,dg,dx,dy,dz;
1293}
1294
1295
1296////////////////////////////////////////////////////////////////////////////////////////////////
1297
1298
1299proc difformNeq(difform df, difform dg)
1300"USAGE:     df != dg; df,dg difform
1301RETURN:     0, if df and dg are euqal - 1, otherwise
1302KEYWORDS:   compare; equal; not equal
1303SEE ALSO:   difformEqu
1304EXAMPLE:    example difformNeq; shows an example"
1305{
1306
1307        return(!difformEqu(df,dg));
1308
1309}
1310example
1311{
1312"EXAMPLE:"; echo = 2;
1313ring R = 0,(x,y,z),ds;
1314diffAlgebra();
1315
1316/////////////////////////////////////////////////
1317// Applications of negated comparison operator //
1318/////////////////////////////////////////////////
1319
1320difform df = 3*dx - x8*dx*dy;
1321difform dg = 3 + x8*dy;
1322df != dg;
1323
1324dg = dg*dx;
1325df != dg;
1326
1327kill Omega_R,df,dg,dx,dy,dz;
1328}
1329
1330
1331////////////////////////////////////////////////////////////////////////////////////////////////
1332
1333
1334proc difformIsBigger(difform df, difform dg, list #)
1335"USAGE:     df > dg OR difformIsBigger(df,dg,#); df,dg difform, # list
1336RETURN:     - 1, if df is bigger than dg with respect to the monomial ordering in the differential algebra - 0, otherwise
1337            - 1, if df is bigger than dg with respect to a given monomial ordering on the generators/ringvariables - 0, otherwise
1338NOTE:       the procedure uses diffAlgebraChangeOrd to change the order on the differential algebra, therefore
1339            an ordering is defined via the following pattern:
1340                - #[i] = 'gen' defines the ordering on the generators dx_i
1341                    - #[i+1] must then be a valid monomial ordering as string
1342                    - #[i+2] an optional weight vector
1343                - #[i] = 'ringvar' defines the ordering on the ringvariables
1344                    - #[i+1] must then be a valid monomial ordering as string
1345                    - #[i+2] an optional weight vector
1346KEYWORDS:   bigger; compare; ordering
1347SEE ALSO:   difformIsSmaller, diffAlgebraChangeOrd
1348EXAMPLE:    example difformIsBigger; shows an example"
1349{
1350
1351    diffAlgebraCheck();
1352    diffAlgebraSwitch();
1353
1354    poly df_form = df.form;
1355    poly dg_form = dg.form;
1356
1357    if(size(#) > 0){
1358        def diff_Alg = basering;
1359        ring T = diffAlgebraChangeOrd(#);
1360
1361        poly df_form_T = imap(diff_Alg,df_form);
1362        poly dg_form_T = imap(diff_Alg,dg_form);
1363        return(df_form_T > dg_form_T);
1364    }
1365
1366    return(df_form > dg_form);
1367
1368}
1369example
1370{
1371"EXAMPLE:"; echo = 2;
1372ring R = 0,(x,y,z),dp;
1373diffAlgebra();
1374
1375////////////////////////////
1376// With standard ordering //
1377////////////////////////////
1378dx > dy;
1379x37*dy > dz;
1380x*dz > y*x*dy;
1381x3*dx - y*dx*dz > dx*dy*dz;
1382
1383///////////////////////////
1384// With changed ordering //
1385///////////////////////////
1386difformIsBigger(dx,dy,"gen","ls");
1387difformIsBigger(x37*dy,dz,"gen","wp",intvec(1,-1,1));
1388difformIsBigger(x*dz,y*x*dy,"gen","wp",intvec(1,-1,1),"ringvar","wp",intvec(1,-1,1));
1389difformIsBigger(x3*dx - y*dx*dz,dx*dy*dz,"gen","wp",intvec(-1,-1,1));
1390
1391kill Omega_R,dx,dy,dz;
1392}
1393
1394
1395////////////////////////////////////////////////////////////////////////////////////////////////
1396
1397
1398proc difformIsSmaller(difform df, difform dg, list #)
1399"USAGE:     df < dg OR difformIsSmaller(df,dg,#); df,dg difform, # list
1400RETURN:     - 1, if df is smaller than dg with respect to the monomial ordering in the differential algebra - 0, otherwise
1401            - 1, if df is smaller than dg with respect to a given monomial ordering on the generators/ringvariables - 0, otherwise
1402NOTE:       the procedure uses diffAlgebraChangeOrd to change the order on the differential algebra, therefore
1403            an ordering is defined via the following pattern:
1404                - #[i] = 'gen' defines the ordering on the generators dx_i
1405                    - #[i+1] must then be a valid monomial ordering as string
1406                    - #[i+2] an optional weight vector
1407                - #[i] = 'ringvar' defines the ordering on the ringvariables
1408                    - #[i+1] must then be a valid monomial ordering as string
1409                    - #[i+2] an optional weight vector
1410KEYWORDS:   smaller; compare; ordering
1411SEE ALSO:   difformIsBigger, diffAlgebraChangeOrd
1412EXAMPLE:    example difformIsSmaller; shows an example"
1413{
1414
1415    diffAlgebraCheck();
1416    diffAlgebraSwitch();
1417
1418    poly df_form = df.form;
1419    poly dg_form = dg.form;
1420
1421    if(size(#) > 0){
1422        def diff_Alg = basering;
1423        ring T = diffAlgebraChangeOrd(#);
1424
1425        poly df_form_T = imap(diff_Alg,df_form);
1426        poly dg_form_T = imap(diff_Alg,dg_form);
1427        return(df_form_T < dg_form_T);
1428    }
1429
1430    return(df.form < dg.form);
1431
1432}
1433example
1434{
1435"EXAMPLE:"; echo = 2;
1436ring R = 0,(x,y,z),lp;
1437diffAlgebra();
1438
1439////////////////////////////
1440// With standard ordering //
1441////////////////////////////
1442dz < dy;
1443x*dz < y*dz;
1444y2*z2*dy < x;
1445dx*dz < dy;
1446
1447///////////////////////////
1448// With changed ordering //
1449///////////////////////////
1450difformIsSmaller(dz,dy,"gen","ls");
1451difformIsSmaller(x*dz,y*dz,"ringvar","ls");
1452difformIsSmaller(y2*z2*dy,x,"gen","wp",intvec(1,-1,1));
1453difformIsSmaller(dx*dz,dy,"gen","ws",intvec(1,-1,-1));
1454
1455kill Omega_R,dx,dy,dz;
1456}
1457
1458
1459////////////////////////////////////////////////////////////////////////////////////////////////
1460//------------------------- Procedures for computing with the degree -------------------------//
1461////////////////////////////////////////////////////////////////////////////////////////////////
1462
1463
1464proc difformDeg(difform df)
1465"USAGE:     deg(df); df difform
1466RETURN:     degree of df - degree of the highest generator, -1 if df = 0
1467NOTE:       - the procedure does not check if df is homogeneous
1468            - be careful: difformDeg does not cast polynomials to differential
1469            forms. So before applying to a polynomial, a type cast should be done
1470KEYWORDS:   degree
1471SEE ALSO:   difformIsHomog, difformIsHomogDeg
1472EXAMPLE:    example difformDeg; shows an example"
1473{
1474
1475    diffAlgebraCheck();
1476    diffAlgebraSwitch();
1477
1478    // Degree of a difform is the degree of the poly with weights 0 for the basering variables
1479    int n = size(ringlist(basering)[2]) div 2;
1480    int i;
1481    intvec var_weights;
1482
1483    for(i = 1; i <= n; i++){
1484        var_weights[i] = 1;
1485        var_weights[i+n] = 0;
1486    }
1487
1488    return(deg(df.form,var_weights));
1489
1490}
1491example
1492{
1493"EXAMPLE:"; echo = 2;
1494ring R = 0,(x,y,z),ds;
1495diffAlgebra();
1496
1497/////////////////////////
1498// Degree computations //
1499/////////////////////////
1500
1501deg(3*dx - x8*dx*dy);
1502deg(3 + x8*dy);
1503
1504// When applying homog to a polynomial which is considered
1505// as a differential form, a type cast has to be done first
1506
1507deg(x2-y);
1508difform df = x2-y;
1509deg(df);
1510
1511kill Omega_R,df,dx,dy,dz;
1512}
1513
1514
1515////////////////////////////////////////////////////////////////////////////////////////////////
1516
1517
1518proc difformIsHomog(difform df)
1519"USAGE:     homog(df); df difform
1520RETURN:     1, if df is homogeneous - 0, otherwise
1521NOTE:       - the form 0 is homogeneous
1522            - be careful: difformIsHomog does not cast polynomials to differential
1523            forms. So before applying to a polynomial, a type cast should be done
1524KEYWORDS:   homogeneous; homog
1525SEE ALSO:   difformDeg, difformIsHomogDeg
1526EXAMPLE:    example difformIsHomog; shows an example"
1527{
1528
1529        diffAlgebraCheck();
1530    diffAlgebraSwitch();
1531
1532    int n = size(ringlist(basering)[2]) div 2;
1533    int i;
1534    intvec var_weights;
1535
1536    for(i = 1; i <= n; i++){
1537        var_weights[i] = 1;
1538        var_weights[i+n] = 0;
1539    }
1540
1541    return(homog(df.form,var_weights));
1542
1543}
1544example
1545{
1546"EXAMPLE:"; echo = 2;
1547ring R = 0,(x,y,z),ds;
1548diffAlgebra();
1549
1550/////////////////
1551// Homogeneous //
1552/////////////////
1553
1554homog(3*dx*dz - x8*dx*dy);
1555homog(12x*dx + dy - (y4-y5)*dz);
1556
1557/////////////////////
1558// Not homogeneous //
1559/////////////////////
1560
1561homog(3 + x8*dy);
1562homog(x*dx+dy*dx);
1563
1564// When applying homog to a polynomial which is considered
1565// as a differential form, a type cast has to be done first
1566
1567homog(3x-y2);
1568difform df = 3x-y2;
1569homog(df);
1570
1571kill Omega_R,dx,dy,dz,df;
1572}
1573
1574
1575////////////////////////////////////////////////////////////////////////////////////////////////
1576
1577
1578proc difformIsHomogDeg(difform df, int p)
1579"USAGE:     difformIsHomogDeg(df,p); df difform, p int
1580RETURN:     1, if df is homogeneous of degree p - 0, otherwise
1581NOTE:       - 0 is homogeneous of degree -1
1582KEYWORDS:   homogeneous; degree
1583SEE ALSO:   difformDeg, difformIsHomog
1584EXAMPLE:    example difformIsHomogDeg; shows an example"
1585{
1586
1587        int df_deg = difformDeg(df);
1588        int is_hom = difformIsHomog(df);
1589        return(df_deg == p && is_hom == 1);
1590
1591}
1592example
1593{
1594"EXAMPLE:"; echo = 2;
1595ring R = 0,(x,y,z),ds;
1596diffAlgebra();
1597
1598difform df = 3*dx*dz - x8*dx*dy;
1599difform dg = 3 + x8*dy;
1600difform dh = 2;
1601difform dt = 0;
1602
1603/////////////////////////////////
1604// Homogeneous of given degree //
1605/////////////////////////////////
1606
1607difformIsHomogDeg(df,2);
1608difformIsHomogDeg(dh,0);
1609difformIsHomogDeg(dt,-1);
1610
1611/////////////////////////////////////
1612// Not homogeneous of given degree //
1613/////////////////////////////////////
1614
1615difformIsHomogDeg(df,1);
1616difformIsHomogDeg(dg,1);
1617difformIsHomogDeg(dh,1);
1618
1619kill Omega_R,df,dg,dh,dt,dx,dy,dz;
1620}
1621
1622
1623////////////////////////////////////////////////////////////////////////////////////////////////
1624
1625
1626proc difformHomogDecomp(difform df)
1627"USAGE:     difformHomogDecomp(df); df difform
1628RETURN:     list of differential forms: homogeneous decomposition
1629NOTE:       the output list always has as length the maximal possible degree plus one and the
1630            degree-0 part is the last element in the list
1631KEYWORDS:   homogeneous; homogeneous decomposition
1632SEE ALSO:   difformCoef, difformDeg
1633EXAMPLE:    example difformHomogDecomp; shows an example"
1634{
1635
1636    diffAlgebraCheck();
1637
1638    // Highest degree is the nr. of variables in the basering
1639    int n = size(ringlist(basering)[2]);
1640    int i,j,k;
1641    difform current_gen;
1642    poly current_coef;
1643    list homog_part;
1644
1645    // Generate a list full of 0s
1646    for(i = 1;i <= (n+1); i++){
1647        homog_part[i] = 0;
1648    }
1649
1650    // Get the generator-representation
1651    list df_gen_repr = difformCoef(df);
1652    k = size(df_gen_repr);
1653
1654    // Sort in list
1655    for(i = 1; i <= k; i++){
1656        current_gen = df_gen_repr[i][1];
1657        current_coef = df_gen_repr[i][2];
1658        j = difformDeg(current_gen);
1659
1660        if(j == 0){
1661            homog_part[n+1] = homog_part[n+1] + current_coef*current_gen;
1662        }else{
1663            homog_part[j] = homog_part[j] + current_coef*current_gen;
1664        }
1665    }
1666
1667    return(homog_part);
1668
1669}
1670example
1671{
1672"EXAMPLE:"; echo = 2;
1673ring R = 0,(x,y,z),ds;
1674diffAlgebra();
1675
1676difform df = 3*dx*dz - x8*dx*dy + 12 + dy*dz + dz*dx - (y4-y5)*x12*dx*dy*dz - dx - dy + dz + x2*dx*dy;
1677
1678///////////////////////////////
1679// Homogeneous decomposition //
1680///////////////////////////////
1681
1682list L = difformHomogDecomp(df);
1683L;
1684
1685kill Omega_R,df,L,dx,dy,dz;
1686}
1687
1688
1689////////////////////////////////////////////////////////////////////////////////////////////////
1690//------------------------ Procedures for lists of differential forms ------------------------//
1691////////////////////////////////////////////////////////////////////////////////////////////////
1692
1693
1694proc difformListCont(list L, difform df)
1695"USAGE:     difformListCont(L,df); L list, df difform
1696RETURN:     1, if df is in the list L - 0, otherwise
1697NOTE:       lists with arbitrary input are allowed
1698KEYWORDS:   containment; list
1699SEE ALSO:   difformEqu
1700EXAMPLE:    example difformListCont; shows an example"
1701{
1702
1703    diffAlgebraCheck();
1704
1705    int n = size(L);
1706    int i;
1707
1708    for(i = 1; i <= n; i++){
1709        if(typeof(L[i]) == "difform"){
1710            if(difformEqu(df,L[i])){
1711                return(1);
1712            }
1713        }
1714    }
1715
1716    return(0);
1717
1718}
1719example
1720{
1721"EXAMPLE:"; echo = 2;
1722ring R = 17,(a,b,c),lp;
1723diffAlgebra();
1724
1725list L = "",3,12*a,da-db,16 + dc, 23*da - 4*db*dc*da, db - 4, "entry", dc - db*da, a;
1726
1727//////////////////////////
1728// Elements in the list //
1729//////////////////////////
1730difformListCont(L,da - db);
1731difformListCont(L,16 + dc);
1732difformListCont(L,dc - db*da);
1733
1734//////////////////////////////
1735// Elements not in the list //
1736//////////////////////////////
1737difformListCont(L,22*da);
1738difformListCont(L,1);
1739difformListCont(L,a);
1740
1741kill Omega_R,L,da,db,dc;
1742}
1743
1744
1745////////////////////////////////////////////////////////////////////////////////////////////////
1746
1747
1748proc difformListSort(list L, list #)
1749"USAGE:     difformListSort(L,#); L,# list
1750RETURN:     the sorted list L in ascending order, depending on the optional monomial ordering given
1751REMARKS:    Classical insertion sort is used to sort the list
1752NOTE:       - the procedure uses difformIsBigger to compare list elements, therefore
1753            an optional ordering is defined via the pattern in difformIsBigger
1754            - the standard ordering is the ordering on the differential algebra
1755            - the procedure can also handle special lists of lists by using the optional input
1756            "Dlist" or "Llist":
1757                - "Dlist" is used for lists with structure:
1758                    L[1] is a list of differential forms
1759                    L[2] is a list of polynomials of same size,
1760                The list gets sorted by the elements in L[1]. This is mainly used for the
1761                structure of derivations.
1762                - "Llist" allows the structure: L[i] is a list with two entries:
1763                    L[i][1] is a differential form
1764                    L[i][2] is a polynomial
1765                The list gets sorted by the elements L[i][1]. This is used to sort
1766                coefficient lists.
1767KEYWORDS:   sort; list
1768SEE ALSO:   difformIsBigger, difformIsSmaller
1769EXAMPLE:    example difformListSort; shows an example"
1770{
1771
1772    diffAlgebraCheck();
1773
1774    list orderings = #;
1775    int n = size(orderings);
1776    int i,j;
1777    int Dlist_flag = 0;
1778    int Llist_flag = 0;
1779
1780    // Check for double list
1781    for(i = 1; i <= n; i++){
1782        if(typeof(orderings[i]) == "string"){
1783            if(orderings[i] == "Dlist"){
1784                Dlist_flag = 1;
1785                orderings = delete(orderings,i);
1786            }
1787        }
1788    }
1789
1790    // Check for list of lists
1791    for(i = 1; i <= n; i++){
1792        if(typeof(orderings[i]) == "string"){
1793            if(orderings[i] == "Llist"){
1794                Llist_flag = 1;
1795                orderings = delete(orderings,i);
1796            }
1797        }
1798    }
1799
1800    // Not both list forms allowed
1801    if(Dlist_flag == 1 && Llist_flag == 1){
1802        ERROR("Cannot sort double list of lists!");
1803    }
1804
1805    // Double list detected
1806    if(Dlist_flag == 1){
1807        poly temp_form_sec;
1808        list L_sec = L[2];
1809        L = L[1];
1810    }
1811
1812    // List of lists detected
1813    if(Llist_flag == 1){
1814        poly temp_form_sec;
1815        n = size(L);
1816        list L_temp;
1817        list L_sec;
1818
1819        // Transform list of lists to double list
1820        for(i = 1; i <= n; i++){
1821            L_temp[i] = L[i][1];
1822            L_sec[i] = L[i][2];
1823        }
1824
1825        L = L_temp;
1826    }
1827
1828    // Insertion sort
1829    difform temp_form;
1830    n = size(L);
1831
1832    for(i = 1; i <= n; i++){
1833        temp_form = L[i];
1834
1835        if(Dlist_flag == 1 || Llist_flag == 1){
1836            temp_form_sec = L_sec[i];
1837        }
1838
1839        j = i;
1840
1841        while(j > 1){
1842            if(difformIsBigger(L[j-1],temp_form,orderings)){
1843                L[j] = L[j-1];
1844
1845                if(Dlist_flag == 1 || Llist_flag == 1){
1846                    L_sec[j] = L_sec[j-1];
1847                }
1848
1849                j--;
1850            }else{
1851                break;
1852            }
1853        }
1854
1855        L[j] = temp_form;
1856
1857        if(Dlist_flag == 1 || Llist_flag == 1){
1858            L_sec[j] = temp_form_sec;
1859        }
1860    }
1861
1862    // For double list - return a double list
1863    if(Dlist_flag == 1){
1864        return(list(L,L_sec));
1865    }
1866
1867    // For list of lists - return a list of lists
1868    if(Llist_flag == 1){
1869        L_temp = list();
1870        for(i = 1; i <= n; i++){
1871            L_temp[i] = list(L[i],L_sec[i]);
1872        }
1873
1874        return(L_temp);
1875    }
1876
1877    return(L);
1878
1879}
1880example
1881{
1882"EXAMPLE:"; echo = 2;
1883ring R = 0,(x,y,z,t),dp;
1884diffAlgebra();
1885
1886/////////////////////////
1887// Sortation of a list //
1888/////////////////////////
1889
1890list L = dx*x, x2 - y*t, 12, dt*dy*dx*dz;
1891
1892// Sort list with standard ordering
1893difformListSort(L);
1894// Sort list with changed ordering
1895difformListSort(L,"gen","ls","ringvar","wp",intvec(-1,1,1,1));
1896
1897/////////////////////////////////////////////
1898// Sortation of list with strcture "Dlist" //
1899/////////////////////////////////////////////
1900
1901list DL;
1902DL[1] = list(dx,x,t,dt); DL[2] = list(y,t*z,4,x);
1903
1904// This list has the structure described by "Dlist"
1905difformListSort(DL,"Dlist","ringvar","ls");
1906
1907/////////////////////////////////////////////
1908// Sortation of list with strcture "Llist" //
1909/////////////////////////////////////////////
1910
1911list LL;
1912LL[1] = list(dx,x); LL[2] = list(t*dt,y); LL[3] = list(x,2);
1913
1914// This list has the structure described by "Llist"
1915difformListSort(LL,"Llist");
1916
1917kill Omega_R,dx,dy,dz,dt,L,DL,LL;
1918}
1919
1920
1921////////////////////////////////////////////////////////////////////////////////////////////////
1922//------------ Procedures for computing with universal derivation and differential -----------//
1923////////////////////////////////////////////////////////////////////////////////////////////////
1924
1925
1926proc difformUnivDer(poly f)
1927"USAGE:     difformUnivDer(f); f poly
1928RETURN:     a differential form: the image of the universal derivation applied to f
1929KEYWORDS:   derivation; universal
1930SEE ALSO:   difformDiff
1931EXAMPLE:    example difformUnivDer; shows an example"
1932{
1933
1934    diffAlgebraCheck();
1935
1936        difform df = 0;
1937    difform d_var;
1938        int n = size(ringlist(basering)[2]);
1939        int i;
1940
1941        // Build the image under the universal derivation
1942        for(i = 1; i <= n; i++){
1943        execute("d_var = d" + string(var(i)));
1944                df = df + diff(f,var(i))*d_var;
1945        }
1946
1947        return(df);
1948
1949}
1950example
1951{
1952"EXAMPLE:"; echo = 2;
1953ring R = 0,(x,y,z),lp;
1954diffAlgebra();
1955
1956/////////////////////////////////////////////////
1957// Universal derivation applied to polynomials //
1958/////////////////////////////////////////////////
1959
1960difformUnivDer(3x);
1961difformUnivDer(xyz+x2y2z2);
1962difformUnivDer(x+y+z);
1963
1964kill Omega_R,dx,dy,dz;
1965}
1966
1967
1968////////////////////////////////////////////////////////////////////////////////////////////////
1969
1970
1971proc difformDiff(difform df)
1972"USAGE:     difformDiff(df); df difform
1973RETURN:     the image of df under the differential
1974REMARK:     To compute the image, the universal derivation is applied to each coefficient and multiplied with the
1975            corresponding generator
1976NOTE:       - the differential is a map Omega_R^(p) -> Omega_R^(p+1) and this procedure applies
1977            the differential to all homogeneous parts of df
1978            - this procedure can also be apllied to polynomials - in this case it is just the universal derivation
1979KEYWORDS:   differential; universal; derivation
1980SEE ALSO:   difformUnivDer
1981EXAMPLE:    example difformDiff; shows an example"
1982{
1983
1984    diffAlgebraCheck();
1985
1986    difform d_df = 0;
1987    list df_gen_repr = difformCoef(df);
1988    int n = size(df_gen_repr);
1989    int i;
1990
1991    // Derivate each coefficient
1992    for(i = 1; i <= n; i++){
1993        d_df = d_df + difformUnivDer(df_gen_repr[i][2])*df_gen_repr[i][1];
1994    }
1995
1996    return(d_df);
1997
1998}
1999example
2000{
2001"EXAMPLE:"; echo = 2;
2002ring R = 0,(x,y,z,a,b,c),lp;
2003diffAlgebra();
2004
2005////////////////////////////////////////
2006// Construction of differential forms //
2007////////////////////////////////////////
2008
2009difform df_1 = y*dx + z*dy + x*dz + a*db + b*dc + c*da;
2010difform df_2 = -5*c4*dc*dz*dy + 3*dx*dz - 13*a4*da*db + 12*a4*da*db + x8*dx*dy + 12 + dy*da + dz*dx - (y4-y5)*x12*dx*db*dz - dx - dy + db + x2*db*dy;
2011poly f = 3x2y2 - z3*c;
2012
2013///////////////////////////////////////
2014// Differential applied to the forms //
2015///////////////////////////////////////
2016
2017difformDiff(df_1);
2018difformDiff(df_2);
2019difformDiff(f);
2020
2021// The composition of differentials is the zero-map:
2022difformDiff(difformDiff(df_1));
2023
2024kill Omega_R,df_1,df_2,f,dx,dy,dz,da,db,dc;
2025}
2026
2027
2028////////////////////////////////////////////////////////////////////////////////////////////////
2029////////////////////////////////////////////////////////////////////////////////////////////////
2030//                               Procedures for type derivation                               //
2031////////////////////////////////////////////////////////////////////////////////////////////////
2032////////////////////////////////////////////////////////////////////////////////////////////////
2033
2034
2035////////////////////////////////////////////////////////////////////////////////////////////////
2036//----------------------------------- Structural procedures ----------------------------------//
2037////////////////////////////////////////////////////////////////////////////////////////////////
2038
2039
2040proc derivationFromList(list L)
2041"USAGE:     derivation phi = derivationFromList(L); L list
2042RETURN:     the derivation defined by the list L
2043REMARKS:    The structure of L is checked and L is sorted,
2044            then it is set as structure list of phi
2045NOTE:       the structure of L must follow the rules:
2046                - L[1] is a list of all degree-1 generators: all dx_i must occure once and no other
2047                differential forms are allowed. The order of the list is not important
2048                - L[2] is the list of images of the dx_i: these must be polynomials
2049            Since the map is linear, it is enough to store the images of the dx_i
2050KEYWORDS:   constructor; derivation
2051SEE ALSO:   derivationCheckList, derivationConstructor, derivationFromPoly
2052EXAMPLE:    example derivationFromList; shows an example"
2053{
2054
2055    diffAlgebraCheck();
2056
2057    // Check the structure of the given list
2058    derivationCheckList(L);
2059
2060    // Sort the generators by the monomial ordering given in the differential algebra
2061    L = difformListSort(L,"Dlist");
2062
2063    derivation phi;
2064    phi.genIm = L;
2065
2066    return(phi);
2067
2068}
2069example
2070{
2071"EXAMPLE:"; echo = 2;
2072ring R = 11,(u,v,w,x),lp;
2073diffAlgebra();
2074
2075/////////////////////////////////////
2076// Construction of structure lists //
2077/////////////////////////////////////
2078
2079list L_1;
2080L_1[1] = list(du,dv,dw,dx);
2081L_1[2] = list(u,v,w,x);
2082
2083list L_2;
2084L_2[1] = list(dx,dw,du,dv);
2085L_2[2] = list(x2,w2,u2,v-wu);
2086
2087/////////////////////////////////
2088// Construction of derivations //
2089/////////////////////////////////
2090
2091derivation phi = derivationFromList(L_1); phi;
2092derivation psi = derivationFromList(L_2); psi;
2093
2094kill Omega_R,du,dv,dw,dx,phi,psi,L_1,L_2;
2095}
2096
2097
2098////////////////////////////////////////////////////////////////////////////////////////////////
2099
2100
2101proc derivationCheckList(list L)
2102"USAGE:     derivationCheckList(L); L list
2103REMARKS:    The procedure checks if a given list has the right form for a derivation
2104            and throws an error if this is not the case. In particular:
2105                - Only degree-1 generators are allowed in L[1] - this is checked via difformIsGen
2106                - Any degree-1 generator must occur once - this is checked via difformListCont
2107NOTE:       like in derivationFromList, the structure of L must follow the rules:
2108                - L[1] is a list of all degree-1 generators: all dx_i must occure once and no other
2109                differential forms are allowed. The order of the list is not important
2110                - L[2] is the list of images of the dx_i: these must be polynomials
2111KEYWORDS:   constructor; derivation; structure
2112SEE ALSO:   derivationFromList, difformIsGen, difformListCont"
2113{
2114
2115    if(size(L) != 2){
2116        ERROR("Given list has wrong size!");
2117    }
2118
2119    if(typeof(L[1]) != "list" || typeof(L[2]) != "list"){
2120        ERROR("Given list does not contain lists!");
2121    }
2122
2123    if(size(L[1]) != size(L[2])){
2124        ERROR("Given list does not have the right form!");
2125    }
2126
2127    int n = size(L[1]);
2128    int i;
2129
2130    // Need an image for any generator
2131    if(n != size(ringlist(basering)[2])){
2132        ERROR("Given list has wrong size!");
2133    }
2134
2135    for(i = 1; i <= n; i++){
2136        // Right type needed
2137        if(typeof(L[1][i]) != "difform" || (typeof(L[2][i]) != "poly" && typeof(L[2][i]) != "int" && typeof(L[2][i]) != "number")){
2138            ERROR("Given list contains wrong type!");
2139        }
2140
2141        // Generator of Omega_R^1
2142        if(!(difformIsGen(L[1][i]) && deg(L[1][i]) == 1)){
2143            ERROR("Given list contains a non-generator or a generator not of degree 1!");
2144        }
2145    }
2146
2147    // Now check the list L[1] for duplicates of the generators
2148    list L_i;
2149    for(i = 1; i <= n; i++){
2150        L_i = delete(L[1],i);
2151        if(difformListCont(L_i,L[1][i])){
2152            ERROR("Given list contains duplicate of a generator!");
2153        }
2154    }
2155}
2156
2157
2158////////////////////////////////////////////////////////////////////////////////////////////////
2159
2160
2161proc derivationFromPoly(poly f)
2162"USAGE:     derivation phi = derivationFromPoly(f); f poly
2163RETURN:     a derivation which maps any degree-1 generator to f
2164REMARKS:    The degree-1 generators are returned by diffAlgebraListGen
2165NOTE:       the procedure allows to interprete polynomials as derivations
2166KEYWORDS:   constructor; derivation; polynomial
2167SEE ALSO:   derivationConstructor, derivationFromList
2168EXAMPLE:    example derivationFromPoly; shows an example"
2169{
2170
2171    diffAlgebraCheck();
2172
2173    list L;
2174    // First entry of list are the degree-1 generators
2175    L[1] = list();
2176    // These are ordered by ordering of differential algebra
2177    L[1] = diffAlgebraListGen(1);
2178
2179    L[2] = list();
2180    int n = size(L[1]);
2181    int i;
2182    for(i = 1; i <= n; i++){
2183        L[2][i] = f;
2184    }
2185
2186    // Construct the derivation
2187    derivation phi;
2188    phi.genIm = L;
2189    return(phi);
2190
2191}
2192example
2193{
2194"EXAMPLE:"; echo = 2;
2195ring R = 0,(x,y,z),lp;
2196diffAlgebra();
2197
2198//////////////////////////////////////////////////
2199// Construction of derivations from polynomials //
2200//////////////////////////////////////////////////
2201
2202derivation phi = derivationFromPoly(3x*y - 12*y4-z2); phi;
2203derivation psi = derivationFromPoly(0); psi;
2204
2205kill Omega_R,dx,dy,dz,phi,psi;
2206}
2207
2208
2209////////////////////////////////////////////////////////////////////////////////////////////////
2210
2211
2212proc derivationConstructor(def inp)
2213"USAGE:     derivation phi = inp; inp of any type
2214RETURN:     the derivation defined by inp:
2215REMARKS:    the output depens on the type of inp:
2216                - if inp is of type list, the constructor derivationFromList is used
2217                - if inp is of type poly, number, int or bigint, derivationFromPoly is used
2218NOTE:       for other than the mentioned types, there is no output
2219KEYWORDS:   constructor; derivation
2220SEE ALSO:   derivationFromList, derivationFromPoly
2221EXAMPLE:    example derivationConstructor; shows an example"
2222{
2223
2224    if(typeof(inp) == "list"){
2225        derivation der_cons = derivationFromList(inp);
2226        return(der_cons);
2227    }
2228    if(typeof(inp) == "poly" || typeof(inp) == "number" || typeof(inp) == "int" || typeof(inp) == "bigint"){
2229        derivation der_cons = derivationFromPoly(inp);
2230        return(der_cons);
2231    }
2232}
2233example
2234{
2235"EXAMPLE:"; echo = 2;
2236ring R = 31,(x,y,z),dp;
2237diffAlgebra();
2238
2239////////////////////////////////////////////////////////////
2240// Construction of derivations from lists and polynomials //
2241////////////////////////////////////////////////////////////
2242
2243list L; L[1] = list(dx,dz,dy); L[2] = list(x2,y-x,z);
2244derivation phi = L; phi;
2245
2246derivation psi = 3x2-12z; psi;
2247
2248kill Omega_R,dx,dy,dz,phi,psi;
2249}
2250
2251
2252////////////////////////////////////////////////////////////////////////////////////////////////
2253
2254
2255proc derivationToString(derivation phi, list #)
2256"USAGE:     derivationToString(phi,#); phi derivation, # list
2257RETURN:     the derivation as a string, describing the image of the degree-1 generators,
2258            optionally ordered by a given monomial ordering on the generators
2259REMARKS:    To sort the images of the generators in the output string, difformListSort is used.
2260NOTE:       to define an ordering for the generators, one can use:
2261                - #[1] = 'gen'
2262                - #[2]: a monomial ordering as string
2263                - #[3]: an optional weight vector
2264            the standard ordering is the ordering of the differential algebra
2265KEYWORDS:   string; print
2266SEE ALSO:   derivationPrint, difformListSort, difformGenToString
2267EXAMPLE:    example derivationToString; shows an example"
2268{
2269
2270    diffAlgebraCheck();
2271    list temp_genIm = phi.genIm;
2272
2273    // Get the optional ordering on the generators
2274    string gen_ord = "";
2275    int n = size(#);
2276    int i;
2277
2278    for(i = 1; i <= n; i++){
2279        if(typeof(#[i]) == "string"){
2280            if(#[i] == "gen" && typeof(#[i+1]) == "string"){
2281                gen_ord = #[i+1];
2282                if(typeof(#[i+2]) == "intvec"){
2283                    intvec gen_weight = #[i+2];
2284                }
2285            }
2286        }
2287    }
2288
2289    // Sort the generator/coefficients by the chosen ordering
2290    if(gen_ord != ""){
2291        if(defined(gen_weight)){
2292            temp_genIm = difformListSort(temp_genIm,"Dlist","gen",gen_ord,gen_weight);
2293        }else{
2294            temp_genIm = difformListSort(temp_genIm,"Dlist","gen",gen_ord);
2295        }
2296    }
2297
2298    list gens = temp_genIm[1];
2299    list images = temp_genIm[2];
2300    n = size(gens);
2301
2302    // Transform to string
2303    string ring_name = nameof(basering);
2304    string phi_out = " Omega_" + ring_name + "^1 --> " + ring_name + newline;
2305    int ring_name_size = size(ring_name);
2306
2307    for(i = 1; i <= n; i++){
2308        phi_out = phi_out + tab(6 + ring_name_size) + difformGenToString(gens[i]) + " |--> " + string(images[i]) + newline;
2309    }
2310
2311    return(phi_out);
2312
2313}
2314example
2315{
2316"EXAMPLE:"; echo = 2;
2317ring R = 0,(x,y,z),dp;
2318diffAlgebra();
2319
2320list L; L[1] = list(dx,dy,dz); L[2] = list(x2,y-23xz,xz4);
2321derivation phi = L;
2322
2323///////////////////////////////////
2324// String with standard ordering //
2325///////////////////////////////////
2326
2327print(derivationToString(phi));
2328
2329//////////////////////////////////
2330// String with changed ordering //
2331//////////////////////////////////
2332
2333print(derivationToString(phi,"gen","wp",intvec(-1,-1,1)));
2334
2335kill Omega_R,dx,dy,dz,L,phi;
2336}
2337
2338
2339////////////////////////////////////////////////////////////////////////////////////////////////
2340
2341
2342proc derivationPrint(derivation phi)
2343"USAGE:         phi; phi derivation
2344SIDE EFFECTS:   prints the given derivation
2345REMARKS:        Prints the string returned by derivationToString with a ls-ordering on the generators
2346KEYWORDS:       print; string
2347SEE ALSO:       derivationToString
2348EXAMPLE:        example derivationPrint; shows an example"
2349{
2350
2351    // Orders the generators in ls-order
2352    print(derivationToString(phi,"gen","ls"));
2353
2354}
2355example
2356{
2357"EXAMPLE:"; echo = 2;
2358ring R = 0,(a,b,c,x,y,z),lp;
2359diffAlgebra();
2360
2361/////////////////
2362// Derivations //
2363/////////////////
2364
2365list L; L[1] = list(dx,dy,dz,da,db,dc); L[2] = list(1,12x-y,z4aby, 2*b5x,0,xyz-abc);
2366derivation phi = L;
2367derivation phi_poly = 3ab - c2*x + z;
2368
2369///////////////////////////
2370// Applications of Print //
2371///////////////////////////
2372
2373phi;
2374phi_poly;
2375
2376kill Omega_R,da,db,dc,dx,dy,dz,L,phi,phi_poly;
2377}
2378
2379
2380////////////////////////////////////////////////////////////////////////////////////////////////
2381//------------------------------ Basic computational procedures ------------------------------//
2382////////////////////////////////////////////////////////////////////////////////////////////////
2383
2384
2385proc derivationAdd(derivation phi, derivation psi)
2386"USAGE:     phi+psi; phi,psi derivation
2387RETURN:     the sum of the given derivations
2388REMARK:     The sum is computed componentwise - this works since the structure lists
2389            of derivations are sorted the same way.
2390NOTE:       once can also add polynomials and derivations
2391KEYWORDS:   add; sum
2392SEE ALSO:   derivationSub
2393EXAMPLE:    example derivationAdd; shows an example"
2394{
2395
2396    diffAlgebraCheck();
2397
2398    // Structure for derivation
2399    derivation add_der;
2400    list add_list;
2401    add_list[1] = list();
2402    add_list[2] = list();
2403    add_list[1] = phi.genIm[1];
2404
2405    int n = size(add_list[1]);
2406    int i;
2407
2408    for(i = 1; i <= n; i++){
2409        // Lists are sorted the same way
2410        add_list[2][i] = phi.genIm[2][i] + psi.genIm[2][i];
2411    }
2412
2413    // The list is already sorted
2414    add_der.genIm = add_list;
2415    return(add_der);
2416
2417}
2418example
2419{
2420"EXAMPLE:"; echo = 2;
2421ring R = 0,(x,y,z),ds;
2422diffAlgebra();
2423
2424list L_1; L_1[1] = list(dx,dy,dz); L_1[2] = list(2x,2y,2z);
2425list L_2; L_2[1] = list(dx,dy,dz); L_2[2] = list(y2-x,z4+x+y,y2);
2426
2427/////////////////
2428// Derivations //
2429/////////////////
2430
2431derivation phi_1 = L_1; phi_1;
2432derivation phi_2 = L_2; phi_2;
2433
2434////////////////////////
2435// Sum of derivations //
2436////////////////////////
2437
2438phi_1 + phi_2;
2439phi_1 + phi_2 + phi_2;
2440phi_1 + phi_2 + 3x2;
2441
2442kill Omega_R,dx,dy,dz,L_1,L_2,phi_1,phi_2;
2443}
2444
2445
2446////////////////////////////////////////////////////////////////////////////////////////////////
2447
2448
2449proc derivationSub(derivation phi, derivation psi)
2450"USAGE:     phi-psi; phi,psi derivation
2451RETURN:     the difference of the given derivations
2452REMARKS:    The difference is computed componentwise - this works since the
2453            structure lists of derivations are sorted the same way.
2454NOTE:       one can also subtract polynomials from derivations
2455KEYWORDS:   minus; difference
2456SEE ALSO:   derivationAdd, derivationNeg
2457EXAMPLE:    example derivationSub; shows an example"
2458{
2459
2460    diffAlgebraCheck();
2461
2462    // Structure for derivation
2463    derivation sub_der;
2464    list sub_list;
2465    sub_list[1] = list();
2466    sub_list[2] = list();
2467    sub_list[1] = phi.genIm[1];
2468
2469    int n = size(sub_list[1]);
2470    int i;
2471
2472    for(i = 1; i <= n; i++){
2473        // Lists are sorted the same way
2474        sub_list[2][i] = phi.genIm[2][i] - psi.genIm[2][i];
2475    }
2476
2477    // The list is already sorted
2478    sub_der.genIm = sub_list;
2479    return(sub_der);
2480
2481}
2482example
2483{
2484"EXAMPLE:"; echo = 2;
2485ring R = 0,(x,y),lp;
2486diffAlgebra();
2487
2488list L_1; L_1[1] = list(dx,dy); L_1[2] = list(x+y,1);
2489list L_2; L_2[1] = list(dy,dx); L_2[2] = list(x,y2);
2490
2491/////////////////
2492// Derivations //
2493/////////////////
2494
2495derivation phi_1 = L_1; phi_1;
2496derivation phi_2 = L_2; phi_2;
2497
2498///////////////////////////////
2499// Difference of derivations //
2500///////////////////////////////
2501
2502phi_1-phi_2;
2503phi_1-phi_2-phi_1;
2504phi_1 - (x+y);
2505
2506kill Omega_R,dx,dy,L_1,L_2,phi_1,phi_2;
2507}
2508
2509
2510////////////////////////////////////////////////////////////////////////////////////////////////
2511
2512
2513proc derivationNeg(derivation phi)
2514"USAGE:     -phi; phi derivation
2515RETURN:     the negation of a given derivation
2516KEYWORDS:   minus; difference
2517SEE ALSO:   derivationSub
2518EXAMPLE:    example derivationNeg; shows an example"
2519{
2520
2521    diffAlgebraCheck();
2522
2523    // Structure for derivation
2524    derivation neg_der;
2525    list neg_list;
2526    neg_list[1] = list();
2527    neg_list[2] = list();
2528    neg_list[1] = phi.genIm[1];
2529
2530    int n = size(neg_list[1]);
2531    int i;
2532
2533    for(i = 1; i <= n; i++){
2534        neg_list[2][i] = -phi.genIm[2][i];
2535    }
2536
2537    // The list is already sorted
2538    neg_der.genIm = neg_list;
2539    return(neg_der);
2540
2541}
2542example
2543{
2544"EXAMPLE:"; echo = 2;
2545ring R = 0,(x,y,z,t),dp;
2546diffAlgebra();
2547
2548list L_1; L_1[1] = list(dy,dx,dt,dz); L_1[2] = list(x2-y,23y+t,tz4,z-y);
2549
2550/////////////////
2551// Derivations //
2552/////////////////
2553
2554derivation phi_1 = L_1; phi_1;
2555derivation phi_poly = 3xyz; phi_poly;
2556
2557/////////////////////////////
2558// Negation of derivations //
2559/////////////////////////////
2560
2561-phi_1;
2562-(-phi_1);
2563-(phi_poly);
2564
2565kill Omega_R,dx,dy,dz,dt,L_1,phi_1,phi_poly;
2566}
2567
2568
2569////////////////////////////////////////////////////////////////////////////////////////////////
2570
2571
2572proc derivationMul(derivation phi, derivation psi)
2573"USAGE:     phi*psi; phi,psi derivation
2574RETURN:     the componentwise product of phi and psi
2575REMARKS:    The product is computed componentwise - this works since the
2576            structure lists of derivations are sorted the same way.
2577NOTE:       one can also multiply polynomials and derivations
2578KEYWORDS:   multiplication; product
2579EXAMPLE:    derivationMul; shows an example"
2580{
2581
2582    diffAlgebraCheck();
2583
2584    // Structure for derivation
2585    derivation mul_der;
2586    list mul_list;
2587    mul_list[1] = list();
2588    mul_list[2] = list();
2589    mul_list[1] = phi.genIm[1];
2590
2591    int n = size(mul_list[1]);
2592    int i;
2593
2594    for(i = 1; i <= n; i++){
2595        // Lists are sorted the same way
2596        mul_list[2][i] = phi.genIm[2][i]*psi.genIm[2][i];
2597    }
2598
2599    // The list is already sorted
2600    mul_der.genIm = mul_list;
2601    return(mul_der);
2602
2603}
2604example
2605{
2606"EXAMPLE:"; echo = 2;
2607ring R = 0,(a,b,t),ls;
2608diffAlgebra();
2609
2610list L_1; L_1[1] = list(da,dt,db); L_1[2] = list(2a,2t-b,2t);
2611list L_2; L_2[1] = list(dt,db,da); L_2[2] = list(-a,-b,-t);
2612
2613/////////////////
2614// Derivations //
2615/////////////////
2616
2617derivation phi_1 = L_1; phi_1;
2618derivation phi_2 = L_2; phi_2;
2619
2620///////////////////////////////////
2621// Multiplication of derivations //
2622///////////////////////////////////
2623
2624phi_1*phi_2;
2625phi_1*phi_2*phi_2;
2626phi_2*(3a2-bt);
2627
2628kill Omega_R,da,db,dt,L_1,L_2,phi_1,phi_2;
2629}
2630
2631
2632////////////////////////////////////////////////////////////////////////////////////////////////
2633
2634
2635proc derivationEqu(derivation phi, derivation psi)
2636"USAGE:     phi == psi; phi,psi derivation
2637RETURN:     1, if phi and psi are equal - 0, otherwise
2638REMARKS:    The images of the generators are compared compononentwise - this
2639            works since the structure lists of derivations are sorted the same way.
2640NOTE:       derivations can also be compared to polynomials
2641KEYWORDS:   compare; equal
2642SEE ALSO:   derivationNeq
2643EXAMPLE:    example derivationEqu; shows an example"
2644{
2645
2646    diffAlgebraCheck();
2647
2648    int n = size(phi.genIm[1]);
2649    int i;
2650
2651    for(i = 1; i <= n; i++){
2652        // Lists are sorted the same way
2653        if(phi.genIm[2][i] != psi.genIm[2][i]){
2654            // Different images
2655            return(0);
2656        }
2657    }
2658
2659    // Images are the same
2660    return(1);
2661
2662}
2663example
2664{
2665"EXAMPLE:"; echo = 2;
2666ring R = 0,(u,v),lp;
2667diffAlgebra();
2668
2669list L_1; L_1[1] = list(dv,du); L_1[2] = list(u,-v);
2670
2671/////////////////
2672// Derivations //
2673/////////////////
2674
2675derivation phi_1 = L_1; phi_1;
2676derivation phi_poly = u*v; phi_poly;
2677
2678///////////////////////////////
2679// Comparison of derivations //
2680///////////////////////////////
2681
2682phi_1 == phi_1;
2683phi_1 == phi_poly;
2684phi_poly == u*v;
2685
2686kill Omega_R,du,dv,phi_1,phi_poly;
2687}
2688
2689
2690////////////////////////////////////////////////////////////////////////////////////////////////
2691
2692
2693proc derivationNeq(derivation phi, derivation psi)
2694"USAGE:     phi != psi; phi,psi derivation
2695RETURN:     0, if phi and psi are equal - 1, otherwise
2696REMARKS:    The comparison is done by difformEqu
2697NOTE:       derivations can also be compared to polynomials
2698KEYWORDS:   compare; equal; not equal
2699SEE ALSO:   derivationEqu
2700EXAMPLE:    example derivationNeq; shows an example"
2701{
2702
2703    return(!derivationEqu(phi,psi));
2704
2705}
2706example
2707{
2708"EXAMPLE:"; echo = 2;
2709ring R = 0,(u,v),lp;
2710diffAlgebra();
2711
2712list L_1; L_1[1] = list(dv,du); L_1[2] = list(u,-v);
2713
2714/////////////////
2715// Derivations //
2716/////////////////
2717
2718derivation phi_1 = L_1; phi_1;
2719derivation phi_poly = u*v; phi_poly;
2720
2721///////////////////////////////
2722// Comparison of derivations //
2723///////////////////////////////
2724
2725phi_1 != phi_1;
2726phi_1 != phi_poly;
2727phi_poly != u*v;
2728
2729kill Omega_R,du,dv,phi_1,phi_poly;
2730}
2731
2732
2733////////////////////////////////////////////////////////////////////////////////////////////////
2734
2735
2736proc derivationEval(derivation phi, difform df)
2737"USAGE:     phi(df); phi derivation, df difform
2738RETURN:     the polynomial phi(df), the derivation phi evaluated at df
2739REMARKS:    - By linearity it is enough to compute the sum of all differential forms:
2740                (coefficient of dx_i)*(image of dx_i)
2741            - The coefficient list of df is computed via difformCoef
2742            - To avoid searching generators in lists, the coefficient list of df and the
2743            structure list of phi are sorted the same way
2744NOTE:       - the differential form 0 is allowed as input
2745            - an error will occure if the given differential form is not of degree 1 or -1
2746KEYWORDS:   evaluation; derivation; application
2747SEE ALSO:   difformListSort, difformCoef
2748EXAMPLE:    example derivationEval; shows an example"
2749{
2750
2751    diffAlgebraCheck();
2752
2753    if(!homog(df)){
2754        ERROR("Cannot apply derivation to non-homogeneous element!");
2755    }
2756
2757    if(deg(df) != 1 && deg(df) != -1){
2758        ERROR("Cannot apply derivation to differential form not of degree 1!");
2759    }
2760
2761    poly df_eval = 0;
2762    list df_gen_repr = difformListSort(difformCoef(df),"Llist");
2763    int k = size(df_gen_repr);
2764    int n = size(phi.genIm[1]);
2765    int i;
2766    int j = 1;
2767
2768    for(i = 1; i <= n; i++){
2769        // Both lists are sorted by the monomial ordering on the differential algebra
2770        // So the generators are sorted the same way in both lists
2771        // If given df does not involve all generators avoid gaps using j
2772        if(j <= k){
2773            if(df_gen_repr[j][1] == phi.genIm[1][i]){
2774                df_eval = df_eval + df_gen_repr[j][2]*phi.genIm[2][i];
2775                j++;
2776            }
2777        }
2778    }
2779
2780    return(df_eval);
2781
2782}
2783example
2784{
2785"EXAMPLE:"; echo = 2;
2786ring R = 13,(x,y,z,t),dp;
2787diffAlgebra();
2788
2789/////////////////////////////////
2790// Construction of derivations //
2791/////////////////////////////////
2792
2793list L_1; L_1[1] = list(dx,dt,dz,dy); L_1[2] = list(x,y,z,t);
2794derivation phi_1 = L_1; phi_1;
2795
2796list L_2; L_2[1] = list(dx,dy,dz,dt); L_2[2] = list(y2x-zt,zt + y, t3-x, y4-y5);
2797derivation phi_2 = L_2; phi_2;
2798
2799list L_3; L_3[1] = list(dx,dy,dz,dt); L_3[2] = list(0,0,0,0);
2800derivation phi_3 = L_3; phi_3;
2801
2802///////////////////////////////
2803// Evaluation of derivations //
2804///////////////////////////////
2805
2806phi_1(0);
2807phi_1(dx+dy+dz+dt);
2808phi_1(3*dx - dt);
2809
2810phi_2(dt);
2811phi_2(dx+dt);
2812phi_2(dx - dy + (x3-y2)*dz + 12*dt);
2813
2814phi_3(dx);
2815phi_3(dy);
2816phi_3(dx - 24*(dx + dz) - x4*dy);
2817
2818kill Omega_R,dx,dy,dz,dt,L_1,L_2,L_3,phi_1,phi_2,phi_3;
2819}
2820
2821
2822////////////////////////////////////////////////////////////////////////////////////////////////
2823//----------------------- Procedures for computing the Lie-Derivative ------------------------//
2824////////////////////////////////////////////////////////////////////////////////////////////////
2825
2826
2827proc derivationContractionGen(derivation phi, difform d_gen)
2828"USAGE:     derivationContractionGen(phi,d_gen); phi derivation, d_gen difform
2829ASSUME:     d_gen is a generator of the differential algebra
2830RETURN:     the image of d_gen under the contraction map i_phi
2831REMARKS:    The formula for the contraction map applied to a generator of degree l is given by:
2832            i_phi^(l)(dx_k*...*dx_j) = sum(i=1,..l)(-1)^(i+1) * phi(dx_i) * (dx_k*...*dx_j / dx_i)
2833NOTE:       this procedure should only be applied to generators
2834KEYWORDS:   contraction; generator
2835SEE ALSO:   derivationContraction"
2836{
2837
2838    // Sort the list, that dx_1 is the first form, dx_2 the second,...
2839    list gen_list = phi.genIm[1];
2840    gen_list = difformListSort(gen_list,"gen","ls");
2841
2842    int n = size(gen_list);
2843    int j = 1;
2844    int i;
2845    difform applic = 0;
2846
2847    // Go through all degree-1 generators and test if, dx_i occurs in d_gen
2848    for(i = 1; i <= n; i++){
2849        if(d_gen / gen_list[i] != 0){
2850            applic = applic + ((-1)^(j+1))*derivationEval(phi,gen_list[i])*(d_gen/gen_list[i]);
2851            j++;
2852        }
2853    }
2854    return(applic);
2855}
2856
2857
2858////////////////////////////////////////////////////////////////////////////////////////////////
2859
2860
2861proc derivationContraction(derivation phi, difform df)
2862"USAGE:     derivationContraction(phi,df); phi derivation, df difform
2863RETURN:     the image of the contraction map i_phi applied to df
2864REMARKS:    Since the contraction map is linear, it is only applied to the generators:
2865            So the image of df under i_phi is a sum, where the coefficients are multiplied
2866            by the image of the generators.
2867NOTE:       over the basering, the contraction map is the 0-map
2868KEYWORDS:   contraction
2869SEE ALSO:   derivationContraction, derivationLie
2870EXAMPLE:    example derivationContraction; shows an example"
2871{
2872
2873    diffAlgebraCheck();
2874
2875    list coef_list = difformCoef(df);
2876    int k = size(coef_list);
2877    int i;
2878    difform applic = 0;
2879
2880    // Apply the contraction map to the generators since it is linear
2881    for(i = 1; i <= k; i++){
2882        applic = applic + coef_list[i][2]*derivationContractionGen(phi,coef_list[i][1]);
2883    }
2884
2885    return(applic);
2886
2887}
2888example
2889{
2890"EXAMPLE:"; echo = 2;
2891ring R = 0,(x,y,z),lp;
2892diffAlgebra();
2893
2894/////////////////////////////////
2895// Construction of derivations //
2896/////////////////////////////////
2897
2898list L_1; L_1[1] = list(dx,dy,dz); L_1[2] = list(x,y,z);
2899derivation phi_1 = L_1; phi_1;
2900
2901list L_2; L_2[1] = list(dx,dy,dz); L_2[2] = list(y-x,z-y,x-z);
2902derivation phi_2 = L_2; phi_2;
2903
2904
2905/////////////////////////////////
2906// Contractions of derivations //
2907/////////////////////////////////
2908
2909derivationContraction(phi_1,dx+dy+dz);
2910derivationContraction(phi_1,x2*y4-z);
2911derivationContraction(phi_1,x2*dx*dy + dx*dy*dz);
2912
2913derivationContraction(phi_2,dx+dy+dz);
2914derivationContraction(phi_2,dx*dy*dz - dx*dy + dx*dz);
2915
2916kill Omega_R,dx,dy,dz,L_1,L_2,phi_1,phi_2;
2917}
2918
2919
2920////////////////////////////////////////////////////////////////////////////////////////////////
2921
2922
2923proc derivationLie(derivation phi, difform df)
2924"USAGE:     diff(phi,df); phi derivation, df difform
2925RETURN:     the image of df under the Lie-derivative L_phi
2926REMARKS:    The map L_phi is the anticommutator of the contraction map i_phi
2927            and the differential d:
2928                (i_phi o d) + (d o i_phi)
2929KEYWORDS:   Lie; contraction
2930SEE ALSO:   derivationContraction, difformDiff
2931EXAMPLE:    example derivationLie; shows an example"
2932{
2933
2934    difform lie_form = derivationContraction(phi,difformDiff(df)) + difformDiff(derivationContraction(phi,df));
2935    return(lie_form);
2936
2937}
2938example
2939{
2940"EXAMPLE:"; echo = 2;
2941ring R = 0,(x,y,z),lp;
2942diffAlgebra();
2943
2944/////////////////////////////////
2945// Construction of derivations //
2946/////////////////////////////////
2947
2948list L; L[1] = list(dx,dy,dz); L[2] = list(x2,y2,z2);
2949derivation phi = L; phi;
2950
2951derivation phi_poly = x-y;
2952
2953///////////////////////////////////
2954// Lie-derivative of derivations //
2955///////////////////////////////////
2956
2957diff(phi,dx);
2958diff(phi,dx*dy);
2959diff(phi,dx*dy*dz);
2960diff(phi,dx*dy + dy*dx);
2961diff(phi,dx*dy - dy*dx);
2962
2963diff(phi_poly,dx);
2964diff(phi_poly,dx-dy);
2965diff(phi_poly,dx+dy);
2966diff(phi_poly,dx*(x2-y4) + 1);
2967
2968kill Omega_R,dx,dy,dz,L,phi,phi_poly;
2969}
2970
2971
2972////////////////////////////////////////////////////////////////////////////////////////////////
2973////////////////////////////////////////////////////////////////////////////////////////////////
2974
2975
2976////////////////////////////////////////////////////////////////////////////////////////////////
2977////////////////////////////////////////////////////////////////////////////////////////////////
2978//                                       Test examples                                        //
2979////////////////////////////////////////////////////////////////////////////////////////////////
2980////////////////////////////////////////////////////////////////////////////////////////////////
2981
2982
2983// EXAMPLE: differential algebra over ring of characteristic 0
2984proc diffAlgebra_example_1(){
2985    ring R = 0,(x,y,z),dp;
2986    diffAlgebra();
2987
2988    exportto(Top,R);
2989}
2990
2991
2992////////////////////////////////////////////////////////////////////////////////////////////////
2993
2994
2995// EXAMPLE: differential algebra over big ring of characteristic 0 and block ordering
2996proc diffAlgebra_example_2(){
2997    ring R = 0,(a,b,x,y,z,t,s,e,r,w,i),(ls(3),dp(4),lp);
2998    diffAlgebra();
2999
3000    exportto(Top,R);
3001}
3002
3003
3004////////////////////////////////////////////////////////////////////////////////////////////////
3005
3006
3007// EXAMPLE: differential algebra over ring of positive characteristic
3008proc diffAlgebra_example_3(){
3009    ring R = 31,(a,b,x),dp;
3010    diffAlgebra();
3011
3012    exportto(Top,R);
3013}
3014
3015
3016////////////////////////////////////////////////////////////////////////////////////////////////
3017
3018
3019// EXAMPLE: differential algebra over quotient ring
3020proc diffAlgebra_example_4(){
3021    ring S = 0,(x,y,z),lp;
3022    ideal I = x2-y4,xyz;
3023    qring R = std(I);
3024    diffAlgebra();
3025
3026    exportto(Top,R);
3027}
3028
3029
3030////////////////////////////////////////////////////////////////////////////////////////////////
3031
3032
3033// EXAMPLE: differential form over ring of characteristic 0
3034proc difform_example_1(){
3035    ring R = 0,(x,y,z),ds;
3036    diffAlgebra();
3037
3038    difform df = 3*dx*x4 + (y4-y5)*dx*dy - dx*dy*dz + 1/7*dz - dx*x2*dz + 8*dy - dy*dz +12;
3039
3040    exportto(Top,R);
3041    exportto(Top,df);
3042}
3043
3044
3045////////////////////////////////////////////////////////////////////////////////////////////////
3046
3047
3048// EXAMPLE: differential form over ring of positive characteristic
3049proc difform_example_2(){
3050    ring R = 31,(x,y,z,a,b,c),lp;
3051    diffAlgebra();
3052
3053    difform df = -5*c4*dc*dz*dy + 3*dx*dz - 13*a4*da*db + 12*a4*da*db + x8*dx*dy + 12 + dy*da + dz*dx - (y4-y5)*x12*dx*db*dz - dx - dy + db + x2*db*dy;
3054
3055    exportto(Top,R);
3056    exportto(Top,df);
3057}
3058
3059
3060////////////////////////////////////////////////////////////////////////////////////////////////
3061
3062
3063// EXAMPLE: derivation by list
3064proc derivation_example_1(){
3065    ring R = 0,(x,y,z),lp;
3066    diffAlgebra();
3067
3068    list L;
3069    L[1] = list(dx,dy,dz);
3070    L[2] = list(x,y,z);
3071
3072    derivation phi = L;
3073
3074    exportto(Top,R);
3075    exportto(Top,phi);
3076}
3077
3078
3079////////////////////////////////////////////////////////////////////////////////////////////////
3080
3081
3082// EXAMPLE: derivation by list
3083proc derivation_example_2(){
3084    ring R = 0,(a,b,c,x,y,z),lp;
3085    diffAlgebra();
3086
3087    list L;
3088    L[1] = list(dx,dy,dz,da,db,dc);
3089    L[2] = list(1,12x-y,z4aby, 2*b5x,0,xyz-abc);
3090    derivation phi = L;
3091
3092    exportto(Top,R);
3093    exportto(Top,phi);
3094}
3095
3096
3097////////////////////////////////////////////////////////////////////////////////////////////////
3098
3099
3100// EXAMPLE: derivations by list
3101proc derivation_example_3(){
3102    ring R = 0,(x,y,z),dp;
3103    diffAlgebra();
3104
3105    list L;
3106    L[1] = list(dx,dy,dz);
3107    L[2] = list(1,x2-y,z+x);
3108    derivation phi_1 = L;
3109
3110    L[1] = list(dx,dy,dz);
3111    L[2] = list(x2,x2,z);
3112    derivation phi_2 = L;
3113
3114    L[1] = list(dx,dy,dz);
3115    L[2] = list(0,3,xyz);
3116    derivation phi_3 = L;
3117
3118    exportto(Top,R);
3119    exportto(Top,phi_1);
3120    exportto(Top,phi_2);
3121    exportto(Top,phi_3);
3122}
3123
3124
Note: See TracBrowser for help on using the repository browser.