Changeset 06df101 in git for libpolys/polys/ext_fields/transext.cc
- Timestamp:
- Jul 6, 2011, 4:41:07 PM (12 years ago)
- Branches:
- (u'spielwiese', '91fdef05f09f54b8d58d92a472e9c4a43aa4656f')
- Children:
- 6c19d854882ab99fd19b9b972a32606106c2f2ee
- Parents:
- 2d3091c7bb239cd4787574560ab475ac88621da7
- git-author:
- Frank Seelisch <seelisch@mathematik.uni-kl.de>2011-07-06 16:41:07+02:00
- git-committer:
- Mohamed Barakat <mohamed.barakat@rwth-aachen.de>2011-11-09 12:39:12+01:00
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libpolys/polys/ext_fields/transext.cc
r2d3091c r06df101 7 7 * transcendental variables t_1, ..., t_s, where s >= 1. 8 8 * Denoting the implemented coeffs object by cf, then these numbers 9 * are represented as quotients of polynomials in the polynomial 10 * ring K[t_1, .., t_s] represented by cf->extring. 9 * are represented as quotients of polynomials living in the 10 * polynomial ring K[t_1, .., t_s] represented by cf->extring. 11 * 12 * An element of K(t_1, .., t_s) may have numerous representations, 13 * due to the possibility of common polynomial factors in the 14 * numerator and denominator. This problem is handled by a 15 * cancellation heuristic: Each number "knows" its complexity 16 * which is 0 if and only if common factors have definitely been 17 * cancelled, and some positive integer otherwise. 18 * Each arithmetic operation of two numbers with complexities c1 19 * and c2 will result in a number of complexity c1 + c2 + some 20 * penalty (specific for each arithmetic operation; see constants 21 * in the *.h file). Whenever the resulting complexity exceeds a 22 * certain threshold (see constant in the *.h file), then the 23 * cancellation heuristic will call 'factory' to compute the gcd 24 * and cancel it out in the given number. (This definite cancel- 25 * lation will also be performed at the beginning of ntWrite, 26 * ensuring that any output is free of common factors. 27 * For the special case of K = Q (i.e., when computing over the 28 * rationals), this definite cancellation procedure will also take 29 * care of nested fractions: If there are fractional coefficients 30 * in the numerator or denominator of a number, then this number 31 * is being replaced by a quotient of two polynomials over Z, or 32 * - if the denominator is a constant - by a polynomial over Q. 11 33 */ 12 34 … … 71 93 void heuristicGcdCancellation(number a, const coeffs cf); 72 94 void definiteGcdCancellation(number a, const coeffs cf, 73 BOOLEAN skipSimpleTests); 95 BOOLEAN simpleTestsHaveAlreadyBeenPerformed); 96 void handleNestedFractionsOverQ(fraction f, const coeffs cf); 74 97 75 98 #ifdef LDEBUG … … 529 552 } 530 553 554 /* assumes that cf represents the rationals, i.e. Q, and will only 555 be called in that case; 556 assumes furthermore that f != NULL and that the denominator of f != 1; 557 generally speaking, this method removes denominators in the rational 558 coefficients of the numerator and denominator of 'a'; 559 more concretely, the following normalizations will be performed, 560 where t^alpha denotes a monomial in the transcendental variables t_k 561 (1) if 'a' is of the form 562 (sum_alpha a_alpha/b_alpha * t^alpha) 563 ------------------------------------- 564 (sum_beta c_beta/d_beta * t^beta) 565 with integers a_alpha, b_alpha, c_beta, d_beta, then both the 566 numerator and the denominator will be multiplied by the LCM of 567 the b_alpha's and the d_beta's (if this LCM is != 1), 568 (2) if 'a' is - e.g. after having performed step (1) - of the form 569 (sum_alpha a_alpha * t^alpha) 570 ----------------------------- 571 (sum_beta c_beta * t^beta) 572 with integers a_alpha, c_beta, and with a non-constant denominator, 573 then both the numerator and the denominator will be divided by the 574 GCD of the a_alpha's and the c_beta's (if this GCD is != 1), 575 (3) if 'a' is - e.g. after having performed steps (1) and (2) - of the 576 form 577 (sum_alpha a_alpha * t^alpha) 578 ----------------------------- 579 c 580 with integers a_alpha, and c != 1, then 'a' will be replaced by 581 (sum_alpha a_alpha/c * t^alpha); 582 this procedure does not alter COM(f) (this has to be done by the 583 calling procedure); 584 modifies f */ 585 void handleNestedFractionsOverQ(fraction f, const coeffs cf) 586 { 587 assume(nCoeff_is_Q(ntCoeffs)); 588 assume(!IS0(f)); 589 assume(!DENIS1(f)); 590 591 if (!p_IsConstant(DEN(f), ntRing)) 592 { /* step (1); see documentation of this procedure above */ 593 number lcmOfDenominators = n_Init(1, ntCoeffs); 594 number c; number tmp; 595 poly p = NUM(f); 596 /* careful when using n_Lcm!!! It computes the lcm of the numerator 597 of the 1st argument and the denominator of the 2nd!!! */ 598 while (p != NULL) 599 { 600 c = p_GetCoeff(p, ntRing); 601 tmp = n_Lcm(lcmOfDenominators, c, ntCoeffs); 602 n_Delete(&lcmOfDenominators, ntCoeffs); 603 lcmOfDenominators = tmp; 604 pIter(p); 605 } 606 p = DEN(f); 607 while (p != NULL) 608 { 609 c = p_GetCoeff(p, ntRing); 610 tmp = n_Lcm(lcmOfDenominators, c, ntCoeffs); 611 n_Delete(&lcmOfDenominators, ntCoeffs); 612 lcmOfDenominators = tmp; 613 pIter(p); 614 } 615 if (!n_IsOne(lcmOfDenominators, ntCoeffs)) 616 { /* multiply NUM(f) and DEN(f) with lcmOfDenominators */ 617 NUM(f) = p_Mult_nn(NUM(f), lcmOfDenominators, ntRing); 618 DEN(f) = p_Mult_nn(DEN(f), lcmOfDenominators, ntRing); 619 } 620 n_Delete(&lcmOfDenominators, ntCoeffs); 621 if (!p_IsConstant(DEN(f), ntRing)) 622 { /* step (2); see documentation of this procedure above */ 623 p = NUM(f); 624 number gcdOfCoefficients = n_Copy(p_GetCoeff(p, ntRing), ntCoeffs); 625 pIter(p); 626 while ((p != NULL) && (!n_IsOne(gcdOfCoefficients, ntCoeffs))) 627 { 628 c = p_GetCoeff(p, ntRing); 629 tmp = n_Gcd(c, gcdOfCoefficients, ntCoeffs); 630 n_Delete(&gcdOfCoefficients, ntCoeffs); 631 gcdOfCoefficients = tmp; 632 pIter(p); 633 } 634 p = DEN(f); 635 while ((p != NULL) && (!n_IsOne(gcdOfCoefficients, ntCoeffs))) 636 { 637 c = p_GetCoeff(p, ntRing); 638 tmp = n_Gcd(c, gcdOfCoefficients, ntCoeffs); 639 n_Delete(&gcdOfCoefficients, ntCoeffs); 640 gcdOfCoefficients = tmp; 641 pIter(p); 642 } 643 if (!n_IsOne(gcdOfCoefficients, ntCoeffs)) 644 { /* divide NUM(f) and DEN(f) by gcdOfCoefficients */ 645 number inverseOfGcdOfCoefficients = n_Invers(gcdOfCoefficients, 646 ntCoeffs); 647 NUM(f) = p_Mult_nn(NUM(f), inverseOfGcdOfCoefficients, ntRing); 648 DEN(f) = p_Mult_nn(DEN(f), inverseOfGcdOfCoefficients, ntRing); 649 n_Delete(&inverseOfGcdOfCoefficients, ntCoeffs); 650 } 651 n_Delete(&gcdOfCoefficients, ntCoeffs); 652 } 653 } 654 if (p_IsConstant(DEN(f), ntRing) && 655 (!n_IsOne(p_GetCoeff(DEN(f), ntRing), ntCoeffs))) 656 { /* step (3); see documentation of this procedure above */ 657 number inverseOfDen = n_Invers(p_GetCoeff(DEN(f), ntRing), ntCoeffs); 658 NUM(f) = p_Mult_nn(NUM(f), inverseOfDen, ntRing); 659 n_Delete(&inverseOfDen, ntCoeffs); 660 p_Delete(&DEN(f), ntRing); 661 DEN(f) = NULL; 662 } 663 664 /* Now, due to the above computations, DEN(f) may have become the 665 1-polynomial which needs to be represented by NULL: */ 666 if ((DEN(f) != NULL) && 667 p_IsConstant(DEN(f), ntRing) && 668 n_IsOne(p_GetCoeff(DEN(f), ntRing), ntCoeffs)) 669 { 670 p_Delete(&DEN(f), ntRing); DEN(f) = NULL; 671 } 672 } 673 531 674 /* modifies a */ 532 675 void heuristicGcdCancellation(number a, const coeffs cf) … … 553 696 /* modifies a */ 554 697 void definiteGcdCancellation(number a, const coeffs cf, 555 BOOLEAN s kipSimpleTests)698 BOOLEAN simpleTestsHaveAlreadyBeenPerformed) 556 699 { 557 700 ntTest(a); … … 559 702 fraction f = (fraction)a; 560 703 561 if (!s kipSimpleTests)704 if (!simpleTestsHaveAlreadyBeenPerformed) 562 705 { 563 706 if (IS0(a)) return; … … 574 717 } 575 718 576 #ifdef HAVE_FACTORY 577 /* singclap_gcd destroys its arguments . We hence need copies: */719 #ifdef HAVE_FACTORY 720 /* singclap_gcd destroys its arguments; we hence need copies: */ 578 721 poly pNum = p_Copy(NUM(f), ntRing); 579 722 poly pDen = p_Copy(DEN(f), ntRing); 723 724 /* Note that, over Q, singclap_gcd will remove the denominators in all 725 rational coefficients of pNum and pDen, before starting to compute 726 the gcd. Thus, we do not need to ensure that the coefficients of 727 pNum and pDen live in Z; they may well be elements of Q\Z. */ 580 728 poly pGcd = singclap_gcd(pNum, pDen, cf->extRing); 581 729 if (p_IsConstant(pGcd, ntRing) && 582 730 n_IsOne(p_GetCoeff(pGcd, ntRing), ntCoeffs)) 583 { 584 /* gcd = 1; nothing to cancel */ 731 { /* gcd = 1; nothing to cancel; 732 Suppose the given rational function field is over Q. Although the 733 gcd is 1, we may have produced fractional coefficients in NUM(f), 734 DEN(f), or both, due to previous arithmetics. The next call will 735 remove those nested fractions, in case there are any. */ 736 if (nCoeff_is_Q(ntCoeffs)) handleNestedFractionsOverQ(f, cf); 585 737 } 586 738 else 587 { 588 poly newNum = singclap_pdivide(NUM(f), pGcd, ntRing); 589 p_Delete(&NUM(f), ntRing); 590 NUM(f) = newNum; 591 poly newDen = singclap_pdivide(DEN(f), pGcd, ntRing); 739 { /* We divide both NUM(f) and DEN(f) by the gcd which is known 740 to be != 1. */ 741 poly newNum = singclap_pdivide(NUM(f), pGcd, ntRing); 742 p_Delete(&NUM(f), ntRing); 743 NUM(f) = newNum; 744 poly newDen = singclap_pdivide(DEN(f), pGcd, ntRing); 745 p_Delete(&DEN(f), ntRing); 746 DEN(f) = newDen; 747 if (p_IsConstant(DEN(f), ntRing) && 748 n_IsOne(p_GetCoeff(DEN(f), ntRing), ntCoeffs)) 749 { 750 /* DEN(f) = 1 needs to be represented by NULL! */ 592 751 p_Delete(&DEN(f), ntRing); 593 if (p_IsConstant(newDen, ntRing) && 594 n_IsOne(p_GetCoeff(newDen, ntRing), ntCoeffs)) 595 { 596 /* newDen = 1 needs to be represented by NULL */ 597 p_Delete(&newDen, ntRing); 598 newDen = NULL; 599 } 600 DEN(f) = newDen; 752 newDen = NULL; 753 } 754 else 755 { /* Note that over Q, by cancelling the gcd, we may have produced 756 fractional coefficients in NUM(f), DEN(f), or both. The next 757 call will remove those nested fractions, in case there are 758 any. */ 759 if (nCoeff_is_Q(ntCoeffs)) handleNestedFractionsOverQ(f, cf); 760 } 601 761 } 602 762 COM(f) = 0;
Note: See TracChangeset
for help on using the changeset viewer.