# source:git/Singular/LIB/difform.lib@69b0fe5

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