source: git/Singular/LIB/ncfrac.lib @ a96a75

fieker-DuValspielwiese
Last change on this file since a96a75 was 6391eb, checked in by Hans Schoenemann <hannes@…>, 5 years ago
version numbers
  • Property mode set to 100644
File size: 32.2 KB
Line 
1//////////////////////////////////////////////////////////////////////
2version="version ncfrac.lib 4.1.2.0 Feb_2019 "; // $Id$
3category="Noncommutative";
4info="
5LIBRARY:   ncfrac.lib  object-oriented interface for olga.lib
6AUTHOR:    Johannes Hoffmann, email: johannes.hoffmann at math.rwth-aachen.de
7
8OVERVIEW:
9This library introduces a new type: ncfrac.
10This type wraps the data defining a (non-commutative) fraction in an Ore
11localization of a G-algebra as in olga.lib.
12An element of type ncfrac has five members:
13  - polys lnum, lden, rnum, rden
14  - ncloc loc
15
16OPERATIONS:
17string(ncfrac);
18  give a string representation of the data describing the fraction
19print(ncfrac);
20  prints the string representation of the fraction
21status(ncfrac);
22  report on the status/validity of the fraction
23test(ncfrac);
24  check if the fraction is valid
25
26INFIX OPERATIONS:
27ncfrac == ncfrac;
28  compare two fractions
29ncfrac != ncfrac;
30  compare two fractions
31ncfrac + ncfrac;
32  add two fractions
33ncfrac - ncfrac
34  subtract two fractions
35ncfrac * ncfrac
36  multiply two fractions
37ncfrac / ncfrac
38  divide two fractions
39ncfrac = int/number/poly
40  create a fraction with:
41    - left and right denominator equal to 1
42    - left and right numerator determined by the input
43    - localization data describing the trivial monoidal localization at 1
44ncfrac = vector
45  create a fraction from a vector v with unspecified localization such that
46  lden,lnum,rnum,rden = v[1],v[2],v[3],v[4]
47  (note: without specifying a localization afterwards this results is an
48  invalid fraction)
49ncfrac = list
50  create a fraction from a list L as follows:
51    - try to create a fraction from L[1] as above
52    - if L[2] is of type ncloc set the localization of the fraction to L[2]
53
54PROCEDURES:
55hasLeftDenom(ncfrac); check if the given fraction has a left representation
56hasRightDenom(ncfrac); check if the given fraction has a right representation
57isZeroNcfrac(ncfrac); check if the given fraction is equal to zero
58isOneNcfrac(ncfrac); check if the given fraction is equal to one
59zeroNcfrac(ncloc loc); create the fraction equal to zero in the given localization
60oneNcfrac(ncloc loc); create the fraction equal to one in the given localization
61ensureLeftNcfrac(ncfrac); compute a left representation of the given fraction if it does not have one
62ensureRightNcfrac(ncfrac); compute a right representation of the given fraction if it does not have one
63negateNcfrac(ncfrac); compute the additive inverse of the given fraction
64isInvertibleNcfrac(ncfrac); check if the given fraction is invertible (note: see the description of
65  isInvertibleLeftFraction from olga.lib for specific behaviour)
66invertNcfrac(ncfrac); compute the multiplicative inverse of the given fraction  (note: see the
67  description of invertLeftFraction from olga.lib for specific behaviour)
68testNcfrac(); execute a series of internal testing procedures
69testNcfracExamples(); execute the examples of all procedures in this library
70";
71//////////////////////////////////////////////////////////////////////
72proc testNcfracExamples()
73"USAGE:   testNcfracExamples()
74PURPOSE: execute the examples of all procedures in this library
75RETURN:  nothing
76NOTE:
77EXAMPLE: "
78{
79    example hasLeftDenom;
80    example hasRightDenom;
81    example isZeroNcfrac;
82    example isOneNcfrac;
83    example zeroNcfrac;
84    example oneNcfrac;
85    example ensureLeftNcfrac;
86    example ensureRightNcfrac;
87}
88//////////////////////////////////////////////////////////////////////
89proc testNcfrac()
90"USAGE:   testNcfrac()
91PURPOSE: execute a series of internal testing procedures
92RETURN:  nothing
93NOTE:
94EXAMPLE: "
95{
96    print("testing ncfrac.lib...");
97    testHasLeftHasRight();
98    testIsZeroIsOne();
99    testNcFracCreation();
100    testNcfracComparison();
101    testNcfracAddition();
102    testNcfracSubtraction();
103    testNcfracMultiplication();
104    testNcfracDivision();
105    testNcfracInversion();
106    testEnsureRightNcfrac();
107    testEnsureLeftNcfrac();
108    print("testing complete - ncfrac.lib OK");
109}
110//////////////////////////////////////////////////////////////////////
111static proc mod_init() {
112    LIB "ncloc.lib";
113    /* new type: ncfrac (non-commutative fraction) */
114    newstruct("ncfrac", "ncloc loc, poly rden, poly rnum, poly lden, poly lnum");
115    system("install", "ncfrac", "print", printNcfrac, 1);
116    system("install", "ncfrac", "string", ncfracToString, 1);
117    system("install", "ncfrac", "=", createNcfrac, 1);
118    system("install", "ncfrac", "==", compareNcfracs, 2);
119    system("install", "ncfrac", "!=", invertedCompareNcfracs, 2);
120    system("install", "ncfrac", "+", addNcfracs, 2);
121    system("install", "ncfrac", "-", subtractNcfracs, 2);
122    system("install", "ncfrac", "*", multiplyNcfracs, 2);
123    system("install", "ncfrac", "/", divideNcfracs, 2);
124    system("install", "ncfrac", "test", testNcfrac, 4);
125    system("install", "ncfrac", "status", statusNcfrac, 4);
126}
127//////////////////////////////////////////////////////////////////////
128proc hasLeftDenom(ncfrac frac)
129"USAGE:   hasLeftDenom(frac), ncfrac frac
130PURPOSE: checks if frac has a left representation
131RETURN:  int, 1 if frac has a left representation, 0 otherwise
132EXAMPLE: example hasLeftDenom; shows example"
133{
134    return(frac.lden != 0);
135}
136example
137{
138    "EXAMPLE:"; echo = 2;
139    ring R = 0,(x,y,Dx,Dy),dp;
140    def S = Weyl();
141    setring S;
142    ncloc loc = ideal(x-3,y+7);
143    ncfrac noLeft = list([0,0,3*y*Dx,x+2], loc);
144    hasLeftDenom(noLeft);
145    ncfrac left = list([1,Dx,Dx,1], loc);
146    hasLeftDenom(left);
147}
148//////////////////////////////////////////////////////////////////////
149proc hasRightDenom(ncfrac frac)
150"USAGE:   hasRightDenom(frac), ncfrac frac
151PURPOSE: checks if frac has a right representation
152RETURN:  int, 1 if frac has a right representation, 0 otherwise
153EXAMPLE: example hasRightDenom; shows example"
154{
155    return(frac.rden != 0);
156}
157example
158{
159    "EXAMPLE:"; echo = 2;
160    ring R = 0,(x,y,Dx,Dy),dp;
161    def S = Weyl();
162    setring S;
163    ncloc loc = ideal(x-3,y+7);
164    ncfrac noRight = list([x+2,3*y*Dx,0,0], loc);
165    hasRightDenom(noRight);
166    ncfrac right = list([1,Dx,Dx,1], loc);
167    hasRightDenom(right);
168}
169////////// status and printing ///////////////////////////////////////
170static proc toVector(ncfrac frac) {
171    return([frac.lden, frac.lnum, frac.rnum, frac.rden]);
172}
173//////////////////////////////////////////////////////////////////////
174static proc statusNcfrac(ncfrac frac) {
175    return(fracStatus(toVector(frac), frac.loc.locType, frac.loc.locData));
176    // fracStatus from olga.lib
177}
178//////////////////////////////////////////////////////////////////////
179static proc testNcfrac(ncfrac frac) {
180    list stat = status(frac);
181    if(!stat[1]) {
182        ERROR(stat[2]);
183    } else {
184        return();
185    }
186}
187//////////////////////////////////////////////////////////////////////
188static proc ncfracToString(ncfrac frac) {
189    list stat = status(frac);
190    if (!stat[1]) {
191        return(stat[2]);
192    } else {
193        return("left repr.: (" + string(frac.lden) + "," + string(frac.lnum)
194          + ")" + newline + "right repr.: (" + string(frac.rnum) + ","
195          + string(frac.rden) + ")");
196    }
197}
198//////////////////////////////////////////////////////////////////////
199static proc printNcfrac(ncfrac frac) {
200    string(frac);
201}
202//////////////////////////////////////////////////////////////////////
203proc isZeroNcfrac(ncfrac frac)
204"USAGE:   isZeroNcfrac(frac), ncfrac frac
205PURPOSE: checks if frac is zero
206RETURN:  int, 1 if frac is zero, 0 otherwise
207EXAMPLE: example isZeroNcfrac; shows example"
208{
209    testNcfrac(frac);
210    if (hasLeftDenom(frac)) { // frac has left representation
211        return(frac.lnum == 0);
212    } else { // frac has right representation, but no left representation
213        return(frac.rnum == 0);
214    }
215}
216example
217{
218    "EXAMPLE:"; echo = 2;
219    ring Q = (0,q),(x,y,Qx,Qy),dp;
220    matrix C[4][4] = UpOneMatrix(4);
221    C[1,3] = q;
222    C[2,4] = q;
223    def ncQ = nc_algebra(C,0);
224    setring ncQ;
225    ncloc loc = intvec(2);
226    ncfrac frac = list([y^2+7*y+1,0,0,0], loc);
227    isZeroNcfrac(frac);
228    frac.lnum = 42*y*Qy+7*Qx+3*x+7;
229    isZeroNcfrac(frac);
230}
231//////////////////////////////////////////////////////////////////////
232proc isOneNcfrac(ncfrac frac)
233"USAGE:   isOneNcfrac(frac), ncfrac frac
234PURPOSE: checks if frac is one
235RETURN:  int, 1 if frac is one, 0 otherwise
236EXAMPLE: example isOneNcfrac; shows example"
237{
238    testNcfrac(frac);
239    if (hasLeftDenom(frac)) { // frac has left representation
240        return(frac.lden == frac.lnum);
241    } else { // frac has right representation, but no left representation
242        return(frac.rden == frac.rnum);
243    }
244}
245example
246{
247    "EXAMPLE:"; echo = 2;
248    ring Q = (0,q),(x,y,Qx,Qy),dp;
249    matrix C[4][4] = UpOneMatrix(4);
250    C[1,3] = q;
251    C[2,4] = q;
252    def ncQ = nc_algebra(C,0);
253    setring ncQ;
254    ncloc loc = intvec(2);
255    ncfrac frac = list([y^2+7*y+1,y^2+7*y+1,0,0], loc);
256    isOneNcfrac(frac);
257    frac.lnum = 42*y*Qy+7*Qx+3*x+7;
258    isOneNcfrac(frac);
259}
260////////// initialization, comparison and declaration ////////////////
261static proc createNcfrac(def input) {
262    string inputType = typeof(input);
263    ncfrac result;
264    if (inputType == "list") {
265        if (size(input) >= 2) {
266            result = createNcfrac(input[1]);
267            if (typeof(input[2]) == "ncloc") {
268                result.loc = input[2];
269            }
270        }
271    }
272    if (inputType == "int" || inputType == "number" || inputType == "poly") {
273        result.lden = poly(1);
274        result.lnum = poly(input);
275        result.rden = poly(1);
276        result.rnum = poly(input);
277        result.loc = ncloc(list(1));
278    }
279    if (inputType == "vector") {
280        result.lden = input[1];
281        result.lnum = input[2];
282        result.rnum = input[3];
283        result.rden = input[4];
284    }
285    return(result);
286}
287//////////////////////////////////////////////////////////////////////
288proc zeroNcfrac(ncloc loc)
289"USAGE:   zeroNcfrac(loc), ncloc loc
290PURPOSE: returns the zero fraction in the localization loc
291RETURN:  ncfrac
292EXAMPLE: example zeroNcfrac; shows example"
293{
294    return(ncfrac(list([1,0,0,1], loc)));
295}
296example
297{
298    "EXAMPLE:"; echo = 2;
299    ring R = 0,(x,y,Dx,Dy),dp;
300    def S = Weyl();
301    setring S;
302    ncloc loc = ideal(x-53,y-7);
303    zeroNcfrac(loc);
304}
305//////////////////////////////////////////////////////////////////////
306proc oneNcfrac(ncloc loc)
307"USAGE:   oneNcfrac(loc), ncloc loc
308PURPOSE: returns the one fraction in the localization loc
309RETURN:  ncfrac
310EXAMPLE: "
311{
312    return(ncfrac(list([1,1,1,1], loc)));
313}
314example
315{
316    "EXAMPLE:"; echo = 2;
317    ring R = 0,(x,y,Dx,Dy),dp;
318    def S = Weyl();
319    setring S;
320    ncloc loc = ideal(x-42,y-17);
321    oneNcfrac(loc);
322}
323//////////////////////////////////////////////////////////////////////
324static proc trimNcfrac(ncfrac frac)
325"USAGE:   trimNcfrac(frac), ncfrac frac
326PURPOSE: simplifies complicated representations of zero and one
327RETURN:  ncfrac
328NOTE:    - if frac is zero, returns the default representation of zero
329         - if frac is one, returns the default representation of one
330         - otherwise returns frac
331EXAMPLE: example trimNcfrac; shows example"
332{
333    testNcfrac(frac);
334    if (isZeroNcfrac(frac)) {
335        return(zeroNcfrac(frac.loc));
336    }
337    if (isOneNcfrac(frac)) {
338        return(oneNcfrac(frac.loc));
339    }
340    return(frac);
341} example {
342    "EXAMPLE:"; echo = 2;
343    ring R = 0,(x,y,Dx,Dy),dp;
344    def S = Weyl();
345    setring S;
346    ncloc loc = poly(x);
347    loc;
348    ncfrac frac1 = list([x^2,x*x,0,0], loc);
349    trimNcfrac(frac1);
350    ncfrac frac2 = list([0,0,0,x], loc);
351    trimNcfrac(frac2);
352}
353//////////////////////////////////////////////////////////////////////
354static proc compareNcfracs(ncfrac frac1, ncfrac frac2) {
355    testNcfrac(frac1);
356    testNcfrac(frac2);
357    if (isZeroNcfrac(frac1)) {
358        return(isZeroNcfrac(frac2));
359    }
360    if (isOneNcfrac(frac1)) {
361        return(isOneNcfrac(frac2));
362    }
363    if (isZeroNcfrac(frac1 - frac2)) {
364        // frac1 and frac2 are equal iff their difference is zero
365        return (1);
366    } else {
367        return (0);
368    }
369}
370//////////////////////////////////////////////////////////////////////
371static proc invertedCompareNcfracs(ncfrac frac1, ncfrac frac2) {
372    return(!compareNcfracs(frac1, frac2));
373}
374////////// compute left resp. right representations //////////////////
375proc ensureLeftNcfrac(ncfrac frac)
376"USAGE:   ensureLeftNcfrac(frac), ncfrac frac
377PURPOSE: ensures that frac has a left representation (by computing it if not
378         alreaDy known)
379RETURN:  ncfrac, a representation of frac which has a left representation
380EXAMPLE: "
381{
382    testNcfrac(frac);
383    if (hasLeftDenom(frac)) {
384        return(frac);
385    }
386    ncloc loc = frac.loc;
387    vector f = toVector(frac);
388    vector result = convertRightToLeftFraction(f, loc.locType, loc.locData);
389    return(ncfrac(list(result, loc)));
390}
391example
392{
393    "EXAMPLE:"; echo = 2;
394    ring R = 0,(x,y,Dx,Dy),dp;
395    def S = Weyl();
396    setring S; S;
397    // monoidal localization
398    poly g1 = x+3;
399    poly g2 = x*y;
400    list L = g1,g2;
401    ncloc loc0 = L;
402    poly g = g1^2*g2;
403    poly f = Dx;
404    ncfrac frac0 = [0,0,f,g];
405    frac0.loc = loc0;
406    ncfrac rm = ensureLeftNcfrac(frac0);
407    print(rm);
408    rm.lnum*g-rm.lden*f;
409    // geometric localization
410    ncloc loc1 = ideal(x-1,y-3);
411    f = Dx;
412    g = x^2+y;
413    ncfrac frac1 = [0,0,f,g];
414    frac1.loc = loc1;
415    ncfrac rg = ensureLeftNcfrac(frac1);
416    print(rg);
417    rg.lnum*g-rg.lden*f;
418    // rational localization
419    intvec rat = 1;
420    ncloc loc2 = rat;
421    f = Dx+Dy;
422    g = x;
423    ncfrac frac2 = [0,0,f,g];
424    frac2.loc = loc2;
425    ncfrac rr = ensureLeftNcfrac(frac2);
426    print(rr);
427    rr.lnum*g-rr.lden*f;
428}
429//////////////////////////////////////////////////////////////////////
430proc ensureRightNcfrac(ncfrac frac)
431"USAGE:   ensureLeftNcfrac(frac), ncfrac frac
432PURPOSE: ensures that frac has a right representation (by computing it if not
433         alreaDy known)
434RETURN:  ncfrac, a representation of frac which has a right representation
435EXAMPLE: "
436{
437    testNcfrac(frac);
438    if (hasRightDenom(frac)) {
439        return (frac);
440    }
441    ncloc loc = frac.loc;
442    vector f = toVector(frac);
443    vector result = convertLeftToRightFraction(f, loc.locType, loc.locData);
444    return(ncfrac(list(result, loc)));
445}
446example
447{
448    "EXAMPLE:"; echo = 2;
449    ring R = 0,(x,y,Dx,Dy),dp;
450    def S = Weyl();
451    setring S; S;
452    // monoidal localization
453    poly g = x;
454    poly f = Dx;
455    ncloc loc0 = g;
456    ncfrac frac0 = [g,f,0,0];
457    frac0.loc = loc0;
458    ncfrac rm = ensureRightNcfrac(frac0);
459    print(rm);
460    f*rm.rden-g*rm.rnum;
461    // geometric localization
462    g = x+y;
463    f = Dx+Dy;
464    ncloc loc1 = ideal(x-1,y-3);
465    ncfrac frac1 = [g,f,0,0];
466    frac1.loc = loc1;
467    ncfrac rg = ensureRightNcfrac(frac1);
468    print(rg);
469    f*rg.rden-g*rg.rnum;
470    // rational localization
471    intvec rat = 1;
472    f = Dx+Dy;
473    g = x;
474    ncloc loc2 = rat;
475    ncfrac frac2 = [g,f,0,0];
476    frac2.loc = loc2;
477    ncfrac rr = ensureRightNcfrac(frac2);
478    print(rr);
479    f*rr.rden-g*rr.rnum;
480}
481////////// arithmetic ////////////////////////////////////////////////
482static proc addNcfracs(ncfrac frac1, ncfrac frac2) {
483    testNcfrac(frac1);
484    testNcfrac(frac2);
485    ncloc loc = frac1.loc;
486    if (loc != frac2.loc) {
487        ERROR("cannot add fractions: incompatible localizations");
488    }
489    vector f1 = toVector(frac1);
490    vector f2 = toVector(frac2);
491    vector result = addLeftFractions(f1, f2, loc.locType, loc.locData, 1);
492    return(ncfrac(list(result, loc)));
493}
494//////////////////////////////////////////////////////////////////////
495proc negateNcfrac(ncfrac frac)
496"USAGE:   negateNcfrac(frac), ncfrac frac
497PURPOSE: compute the negative (i.e. additive inverse) of frac
498RETURN:  ncfrac
499NOTE:    returns (-1)*frac
500EXAMPLE: example negateNcfrac; shows example"
501{
502    ncfrac result = frac;
503    result.lnum = result.lnum * (-1);
504    result.rnum = result.rnum * (-1);
505    return(result);
506}
507example
508{
509    "EXAMPLE:"; echo = 2;
510    ring R = 0,(x,y,Dx,Dy),dp;
511    def S = Weyl();
512    setring S;
513    poly g = x*y^2+4*x+7*y-98;
514    ncloc loc = g;
515    ncfrac frac = list([g, 13*x^2], loc);
516    frac;
517    ncfrac negFrac = negateNcfrac(frac);
518    negFrac;
519    frac + negFrac;
520}
521//////////////////////////////////////////////////////////////////////
522static proc subtractNcfracs(ncfrac frac1, ncfrac frac2) {
523    testNcfrac(frac1);
524    testNcfrac(frac2);
525    if (frac1.loc != frac2.loc) {
526        ERROR("cannot subtract fractions: incompatible localizations");
527    }
528    return(frac1 + negateNcfrac(frac2));
529}
530//////////////////////////////////////////////////////////////////////
531static proc multiplyNcfracs(ncfrac frac1, ncfrac frac2) {
532    testNcfrac(frac1);
533    testNcfrac(frac2);
534    ncloc loc = frac1.loc;
535    if (loc != frac2.loc) {
536        ERROR("cannot multiply fractions: incompatible localizations");
537    }
538    vector f1 = toVector(frac1);
539    vector f2 = toVector(frac2);
540    vector result = multiplyLeftFractions(f1, f2, loc.locType, loc.locData, 1);
541    return(ncfrac(list(result, loc)));
542}
543//////////////////////////////////////////////////////////////////////
544proc isInvertibleNcfrac(ncfrac frac)
545"USAGE:   isInvertibleNcfrac(frac), ncfrac frac
546PURPOSE: checks if frac is invertible
547RETURN:  int, 1 if frac is invertible, 0 otherwise
548EXAMPLE: example isInvertibleNcfrac; shows example"
549{
550    testNcfrac(frac);
551    poly num;
552    if (hasLeftDenom(frac)) { // frac has left representation
553        num = frac.lnum;
554    } else { // frac has right representation, but no left representation
555        num = frac.rnum;
556    }
557    return(isDenom(num, frac.loc));
558}
559example
560{
561    "EXAMPLE:"; echo = 2;
562    ring R = 0,(x,y,Dx,Dy),dp;
563    def S = Weyl();
564    setring S;
565    ncloc loc = intvec(2);
566    ncfrac frac = list([y,y+1,0,0], loc);
567    isInvertibleNcfrac(frac);
568    frac = list([y,x+1,0,0], loc);
569    isInvertibleNcfrac(frac);
570}
571//////////////////////////////////////////////////////////////////////
572proc invertNcfrac(ncfrac frac)
573"USAGE:   invertNcfrac(frac), ncfrac frac
574PURPOSE: compute the inverse of frac
575RETURN:  ncfrac
576NOTE:    returns the zero fraction if frac is not invertible
577EXAMPLE: example invertNcfrac; shows example"
578{
579    ncfrac result;
580    if (!isInvertibleNcfrac(frac)) {
581        result = zeroNcfrac(frac.loc);
582    } else {
583        result = list([frac.lnum, frac.lden, frac.rden, frac.rnum], frac.loc);
584    }
585    return(result);
586}
587example
588{
589    "EXAMPLE:"; echo = 2;
590    ring R = 0,(x,y,Dx,Dy),dp;
591    def S = Weyl();
592    setring S;
593    ncloc loc = intvec(2);
594    ncfrac frac1 = list([y,y+1,0,0], loc);
595    // frac1 is invertible
596    ncfrac inv = invertNcfrac(frac1);
597    inv;
598    ncfrac frac2 = list([y,x+1,0,0], loc);
599    // frac2 is not invertible
600    inv = invertNcfrac(frac2);
601    inv;
602}
603//////////////////////////////////////////////////////////////////////
604static proc divideNcfracs(ncfrac frac1, ncfrac frac2) {
605    testNcfrac(frac1);
606    testNcfrac(frac2);
607    if (frac1.loc != frac2.loc) {
608        ERROR("cannot multiply fractions: incompatible localizations");
609    }
610    if(!isInvertibleNcfrac(frac2)) {
611        ERROR("division by non-invertible fraction");
612    } else {
613        return(frac1 * invertNcfrac(frac2));
614    }
615}
616//////////////////////////////////////////////////////////////////////
617////////// internal testing procedures ///////////////////////////////
618static proc testHasLeftHasRight()
619{
620    print("  testing ncfrac hasLeftDenom/hasRightDenom...");
621    ring r = 0,(x,y,Dx,Dy),dp;
622    def R = Weyl();
623    setring R;
624    ncloc loc = ideal(x-3,y+7);
625    ncfrac noLeft = list([0,0,3*y*Dx,x+2], loc);
626    if (hasLeftDenom(noLeft)) {
627        ERROR("hasLeftDenom noLeft failed");
628    }
629    ncfrac left = list([1,Dx,Dx,1], loc);
630    if (!hasLeftDenom(left)) {
631        ERROR("hasLeftDenom left failed");
632    }
633    ncfrac noRight = list([x+2,3*y*Dx,0,0], loc);
634    if (hasRightDenom(noRight)) {
635        ERROR("hasRightDenom noRight failed");
636    }
637    ncfrac right = list([1,Dx,Dx,1], loc);
638    if (!hasRightDenom(right)) {
639        ERROR("hasRightDenom right failed");
640    }
641    print("    ncloc hasLeftDenom/hasRightDenom OK");
642}
643//////////////////////////////////////////////////////////////////////
644static proc testIsZeroIsOne()
645{
646    print("  testing ncfrac isZeroNcfrac/isOneNcfrac...");
647    ring Q = (0,q),(x,y,Qx,Qy),dp;
648    matrix C[4][4] = UpOneMatrix(4);
649    C[1,3] = q;
650    C[2,4] = q;
651    def ncQ = nc_algebra(C,0);
652    setring ncQ;
653    ncloc loc = intvec(2);
654    ncfrac frac = list([y^2+7*y+1,0,0,0], loc);
655    if (!isZeroNcfrac(frac)) {
656        ERROR("isZeroNcfrac zero failed");
657    }
658    frac.lnum = 42*y*Qy+7*Qx+3*x+7;
659    if (isZeroNcfrac(frac)) {
660        ERROR("isZeroNcfrac non-zero failed");
661    }
662    frac.lnum = frac.lden;
663    //frac = list([y^2+7*y+1,y^2+7*y+1,0,0], loc);
664    if (!isOneNcfrac(frac)) {
665        ERROR("isOneNcfrac one failed");
666    }
667    frac.lnum = 42*y*Qy+7*Qx+3*x+7;
668    if (isOneNcfrac(frac)) {
669        ERROR("isOneNcfrac non-one failed");
670    }
671    print("    ncloc isZeroNcfrac/isOneNcfrac OK");
672}
673//////////////////////////////////////////////////////////////////////
674static proc testNcFracCreation() {
675    print("  testing ncfrac creation...");
676    ring r = 0,(x,y,Dx,Dy),dp;
677    def R = Weyl();
678    setring R;
679    ncloc loc = list(x);
680    ncfrac frac1 = [x,Dx,0,0]; // create from vector
681    frac1.loc = loc;
682    test(frac1);
683    ncfrac frac2 = 7; // create from interface
684    frac2.loc = loc;
685    test(frac2);
686    ncfrac frac3 = 4*x*Dx*Dy*Dy; // create from poly
687    frac3.loc = loc;
688    test(frac3);
689    ncfrac frac4 = list([x^2,Dx], loc); // create from list with vector
690    test(frac4);
691    ncfrac frac5 = list(42, loc); // create from list with int
692    test(frac5);
693    print("    ncfrac creation OK");
694}
695//////////////////////////////////////////////////////////////////////
696static proc testNcfracComparison() {
697    print("  testing ncfrac comparison...");
698    ring r = 0,(x,y,Dx,Dy),dp;
699    def R = Weyl();
700    setring R;
701    // monoidal
702    poly g1 = x*y+3;
703    poly g2 = y^3;
704    ncloc locm = list(g1, g2);
705    ncfrac fracm1 = list([g1,Dx,0,0], locm);
706    ncfrac fracm2 = list([g1*g2,g2*Dx,0,0], locm);
707    ncfrac fracm3 = list([g1*g2,g1*Dx+3,0,0], locm);
708    if (!(fracm1 == fracm2)) {
709        ERROR("Weyl monoidal positive basic comparison error");
710    }
711    if (fracm1 == fracm3) {
712        ERROR("Weyl monoidal first negative basic comparison error");
713    }
714    if (fracm2 == fracm3) {
715        ERROR("Weyl monoidal second negative basic comparison error");
716    }
717    // geometric
718    ideal p = x+5, y-2;
719    ncloc locg = p;
720    ncfrac fracg1 = list([g1,Dx,0,0], locg);
721    ncfrac fracg2 = list([g1*g2,g2*Dx,0,0], locg);
722    ncfrac fracg3 = list([g1*g2,g1*Dx+3,0,0], locg);
723    if (!(fracg1 == fracg2)) {
724        ERROR("Weyl geometric positive basic comparison error");
725    }
726    if (fracg1 == fracg3) {
727        ERROR("Weyl geometric first negative basic comparison error");
728    }
729    if (fracg2 == fracg3) {
730        ERROR("Weyl geometric second negative basic comparison error");
731    }
732    // rational
733    intvec rat = 1,4;
734    ncloc locr = rat;
735    ncfrac fracr1 = list([x+Dy,Dx,0,0], locr);
736    ncfrac fracr2 = list([x*Dy*(x+Dy),x*Dx*Dy,0,0], locr);
737    ncfrac fracr3 = list([Dy*x*(x+Dy),x*Dx*Dy+1,0,0], locr);
738    if (!(fracr1 == fracr2)) {
739        ERROR("Weyl rational positive basic comparison error");
740    }
741    if (fracr1 == fracr3) {
742        ERROR("Weyl rational first negative basic comparison error");
743    }
744    if (fracr2 == fracr3) {
745        ERROR("Weyl rational second negative basic comparison error");
746    }
747    print("    ncfrac comparison OK");
748}
749//////////////////////////////////////////////////////////////////////
750static proc testNcfracAddition() {
751    print("  testing ncfrac addition...");
752    ring R = 0,(x,y,Dx,Dy),dp;
753    def S = Weyl();
754    setring S;
755    poly g1 = x+3;
756    poly g2 = x*y+y;
757    ncloc loc = list(g1,g2);
758    ncfrac frac1 = list([g1,Dx,0,0], loc);
759    ncfrac frac2 = list([g2,Dy,0,0], loc);
760    ncfrac resu = frac1 + frac2;
761    if (resu.lden != g1*g2 || resu.lnum != g2*Dx+g1*Dy) {
762        ERROR("Weyl monoidal addition error");
763    }
764    loc = ideal(x-1,y-3);
765    frac1.loc = loc;
766    frac2.loc = loc;
767    resu = frac1 + frac2;
768    if (resu.lden != g1*g2 || resu.lnum != g2*Dx+g1*Dy) {
769        ERROR("Weyl geometric maximal addition error");
770    }
771    loc = ideal(y+3);
772    frac1.loc = loc;
773    frac2.loc = loc;
774    resu = frac1 + frac2;
775    if (resu.lden != g1*g2 || resu.lnum != g2*Dx+g1*Dy) {
776        ERROR("Weyl geometric prime addition error");
777    }
778    loc = intvec(2);
779    frac1 = list([y^2+y+1,Dx,0,0], loc);
780    frac2 = list([y-2,Dy,0,0], loc);
781    resu = frac1 + frac2;
782    if (resu.lden != (y^2+y+1)*(y-2) || resu.lnum != (y-2)*Dx+(y^2+y+1)*Dy) {
783        ERROR("Weyl rational addition error");
784    }
785    print("    ncfrac addition OK");
786}
787//////////////////////////////////////////////////////////////////////
788static proc testNcfracSubtraction() {
789    print("  testing ncfrac subtraction...");
790    ring R = 0,(x,y,Dx,Dy),dp;
791    def S = Weyl();
792    setring S;
793    poly g1 = x+3;
794    poly g2 = x*y+y;
795    ncloc loc = list(g1,g2);
796    ncfrac frac1 = list([g1,Dx,0,0], loc);
797    ncfrac frac2 = list([g2,-Dy,0,0], loc);
798    ncfrac resu = frac1 - frac2;
799    if (resu.lden != g1*g2 || resu.lnum != g2*Dx+g1*Dy) {
800        ERROR("Weyl monoidal subtraction error");
801    }
802    loc = ideal(x-1,y-3);
803    frac1.loc = loc;
804    frac2.loc = loc;
805    resu = frac1 - frac2;
806    if (resu.lden != g1*g2 || resu.lnum != g2*Dx+g1*Dy) {
807        ERROR("Weyl geometric subtraction error");
808    }
809    loc = intvec(2);
810    frac1 = list([y^2+y+1,Dx,0,0], loc);
811    frac2 = list([y-2,-Dy,0,0], loc);
812    resu = frac1 - frac2;
813    if (resu.lden != (y^2+y+1)*(y-2) || resu.lnum != (y-2)*Dx+(y^2+y+1)*Dy) {
814        ERROR("Weyl rational subtraction error");
815    }
816    print("    ncfrac subtraction OK");
817}
818//////////////////////////////////////////////////////////////////////
819static proc testNcfracMultiplication() {
820    print("  testing ncfrac multiplication...");
821    ring R = 0,(x,y,Dx,Dy),dp;
822    def S = Weyl();
823    setring S;
824    // monoidal localization
825    poly g1 = x+3;
826    poly g2 = x*y+y;
827    ncloc loc = list(g1,g2);
828    ncfrac frac1 = list([g1,Dx,0,0], loc);
829    ncfrac frac2 = list([g2,Dy,0,0], loc);
830    ncfrac resu = frac1 * frac2;
831    if (resu.lden != g1*g2^2 || resu.lnum != x*y*Dx*Dy+y*Dx*Dy-y*Dy) {
832        ERROR("Weyl monoidal multiplication error");
833    }
834    // geometric localization
835    loc = ideal(x-1,y-3);
836    frac1.loc = loc;
837    frac2.loc = loc;
838    resu = frac1 * frac2;
839    if (resu.lden != g1*g2*(x+1) || resu.lnum != x*Dx*Dy+Dx*Dy-Dy) {
840        ERROR("Weyl geometric multiplication error");
841    }
842    // rational localization
843    loc = intvec(2);
844    frac1 = list([y^2+y+1,Dx,0,0], loc);
845    frac2 = list([y-2,Dy,0,0], loc);
846    resu = frac1 * frac2;
847    if (resu.lden != (y^2+y+1)*(y-2) || resu.lnum != Dx*Dy) {
848        ERROR("Weyl rational multiplication (1*2) error");
849    }
850    resu = frac2 * frac1;
851    if (resu.lden != (y^2+y+1)^2*(y-2) || resu.lnum != y^2*Dx*Dy+y*Dx*Dy-2*y*Dx+Dx*Dy-Dx) {
852        ERROR("Weyl rational multiplication (2*1) error");
853    }
854    print("    ncfrac multiplication OK");
855}
856//////////////////////////////////////////////////////////////////////
857static proc testNcfracDivision() {
858    print("  testing ncfrac division...");
859    ring R = 0,(x,y,Dx,Dy),dp;
860    def S = Weyl();
861    setring S;
862    // monoidal localization
863    poly g1 = x+3;
864    poly g2 = x*y+y;
865    ncloc loc = list(g1,g2);
866    ncfrac frac1 = list([g1,Dx,0,0], loc);
867    ncfrac frac2 = list([g2,g1,0,0], loc);
868    ncfrac resu = frac1 / frac2;
869    if (resu.lden != g1^3 || resu.lnum != x^2*y*Dx+4*x*y*Dx+3*y*Dx+2*y) {
870        ERROR("Weyl monoidal division error");
871    }
872    // geometric localization
873    loc = ideal(x-1,y-3);
874    frac1.loc = loc;
875    frac2.loc = loc;
876    resu = frac1 / frac2;
877    if (resu.lden != g1^3 || resu.lnum != x^2*y*Dx+4*x*y*Dx+3*y*Dx+2*y) {
878        ERROR("Weyl geometric division error");
879    }
880    // rational localization
881    loc = intvec(2);
882    frac1 = list([y^2+y+1,Dx,0,0], loc);
883    frac2 = list([y-2,3*y^2-21y+2,0,0], loc);
884    resu = frac1 / frac2;
885    if (resu.lden != 3*y^4-18*y^3-16*y^2-19*y+2 || resu.lnum != (y-2)*Dx) {
886        ERROR("Weyl geometric division error");
887    }
888    print("    ncfrac division OK");
889}
890//////////////////////////////////////////////////////////////////////
891static proc testNcfracInversion() {
892    print("  testing ncfrac invertNcfrac...");
893    ring R = 0,(x,y,Dx,Dy),dp;
894    def S = Weyl();
895    setring S;
896    poly g1 = x+3;
897    poly g2 = x*y;
898    ncfrac frac = list([g1*g2, 17, 0, 0], ncloc(list(g1,g2)));
899    frac = invertNcfrac(frac);
900    if (frac.lden != 17 || frac.lnum != g1*g2) {
901        ERROR("Weyl monoidal inversion error");
902    }
903    frac = list([g1, 3*x, 0, 0], ncloc(ideal(x-1,y)));
904    frac = invertNcfrac(frac);
905    if (frac.lden != 3*x || frac.lnum != x+3) {
906        ERROR("Weyl geometric inversion error");
907    }
908    frac = list([g1*g2, y, 0, 0], ncloc(intvec(1,2)));
909    frac = invertNcfrac(frac);
910    if (frac.lden != y || frac.lnum != g1*g2) {
911        ERROR("Weyl rational inversion error");
912    }
913    print("    ncfrac invertNcfrac OK");
914}
915//////////////////////////////////////////////////////////////////////
916static proc testEnsureRightNcfrac() {
917    print("  testing ncfrac ensureRightNcfrac...");
918    // Weyl
919    ring W = 0,(x,y,Dx,Dy),dp;
920    def ncW = Weyl();
921    setring ncW;
922    //// monoidal localization
923    ncloc monloc = list(x);
924    ncfrac monfrac = list([x,Dx,0,0], monloc);
925    ncfrac monresult = ensureRightNcfrac(monfrac);
926    if (!status(monresult)[1]) {
927        ERROR("Weyl monoidal ensureRightNcfrac failed");
928    }
929    //// geometrical localization
930    ncloc geoloc = ideal(x-1,y-3);
931    ncfrac geofrac = list([x+y,Dx+Dy,0,0], geoloc);
932    ncfrac georesult = ensureRightNcfrac(geofrac);
933    if (!status(georesult)[1]) {
934        ERROR("Weyl geometric ensureRightNcfrac failed");
935    }
936    //// rational localization
937    ncloc ratloc = intvec(1);
938    ncfrac ratfrac = list([x,Dx+Dy], ratloc);
939    ncfrac ratresult = ensureRightNcfrac(ratfrac);
940    if (!status(ratresult)[1]) {
941        ERROR("Weyl rational ensureRightNcfrac failed");
942    }
943    // shift rational localization
944    ring S = 0,(x,y,Sx,Sy),dp;
945    matrix D[4][4];
946    D[1,3] = Sx;
947    D[2,4] = Sy;
948    def ncS = nc_algebra(1, D);
949    setring ncS;
950    ncfrac shiftfrac = list([x,Sx+Sy], ratloc);
951    ncfrac shiftresult = ensureRightNcfrac(shiftfrac);
952    if (!status(shiftresult)[1]) {
953        ERROR("Shift rational ensureRightNcfrac failed");
954    }
955    // q-shift rational localization
956    ring Q = (0,q),(x,y,Qx,Qy),dp;
957    matrix C[4][4] = UpOneMatrix(4);
958    C[1,3] = q;
959    C[2,4] = q;
960    def ncQ = nc_algebra(C, 0);
961    setring ncQ;
962    ncfrac qshiftfrac = list([x,Qx+Qy], ratloc);
963    ncfrac qshiftresult = ensureRightNcfrac(qshiftfrac);
964    if (!status(qshiftresult)[1]) {
965        ERROR("q-shift rational ensureRightNcfrac failed");
966    }
967    print("    ncfrac ensureRightNcfrac OK");
968}
969//////////////////////////////////////////////////////////////////////
970static proc testEnsureLeftNcfrac() {
971    print("  testing ncfrac ensureLeftNcfrac...");
972    // Weyl
973    ring W = 0,(x,y,Dx,Dy),dp;
974    def ncW = Weyl();
975    setring ncW;
976    //// monoidal localization
977    ncloc monloc = list(x+3, x*y);
978    ncfrac monfrac = list([0,0,Dx,(x+3)^2*x], monloc);
979    ncfrac monresult = ensureLeftNcfrac(monfrac);
980    if (!status(monresult)[1]) {
981        ERROR("Weyl monoidal ensureLeftNcfrac failed");
982    }
983    //// geometric localization
984    ncloc geoloc = ideal(x-1,y-3);
985    ncfrac geofrac = list([0,0,Dx,x^2+y], geoloc);
986    ncfrac georesult = ensureLeftNcfrac(geofrac);
987    if (!status(georesult)[1]) {
988        ERROR("Weyl monoidal ensureLeftNcfrac failed");
989    }
990    //// rational localization
991    ncloc ratloc = intvec(1);
992    ncfrac ratfrac = list([0,0,Dx+Dy,x], ratloc);
993    ncfrac ratresult = ensureLeftNcfrac(ratfrac);
994    if (!status(ratresult)[1]) {
995        ERROR("Weyl monoidal ensureLeftNcfrac failed");
996    }
997    // shift rational localization
998    ring S = 0,(x,y,Sx,Sy),dp;
999    matrix D[4][4];
1000    D[1,3] = Sx;
1001    D[2,4] = Sy;
1002    def ncS = nc_algebra(1, D);
1003    setring ncS;
1004    ncfrac shiftfrac = list([0,0,Sx+Sy,x], ratloc);
1005    ncfrac shiftresult = ensureLeftNcfrac(shiftfrac);
1006    if (!status(shiftresult)[1]) {
1007        ERROR("Shift rational ensureLeftNcfrac failed");
1008    }
1009    // q-shift rational localization
1010    ring Q = (0,q),(x,y,Qx,Qy),dp;
1011    matrix C[4][4] = UpOneMatrix(4);
1012    C[1,3] = q;
1013    C[2,4] = q;
1014    def ncQ = nc_algebra(C, 0);
1015    setring ncQ;
1016    ncfrac qshiftfrac = list([0,0,Qx+Qy,x], ratloc);
1017    ncfrac qshiftresult = ensureLeftNcfrac(qshiftfrac);
1018    if (!status(qshiftresult)[1]) {
1019        ERROR("q-shift rational ensureLeftNcfrac failed");
1020    }
1021    print("    ncfrac ensureLeftNcfrac OK");
1022}
1023//////////////////////////////////////////////////////////////////////
Note: See TracBrowser for help on using the repository browser.