Changeset dc79bd in git
- Timestamp:
- Oct 4, 2012, 8:16:12 PM (12 years ago)
- Branches:
- (u'fieker-DuVal', '117eb8c30fc9e991c4decca4832b1d19036c4c65')(u'spielwiese', '38dfc5131670d387a89455159ed1e071997eec94')
- Children:
- 20c54056198f825ef62888512342886cf96c82a6
- Parents:
- 9f6cc091f81a4d6c75b4696ae3e84bc53e419051
- git-author:
- Oleksandr Motsak <motsak@mathematik.uni-kl.de>2012-10-04 20:16:12+02:00
- git-committer:
- Oleksandr Motsak <motsak@mathematik.uni-kl.de>2012-10-05 18:15:05+02:00
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
Singular/maps_ip.cc
r9f6cc0 rdc79bd 259 259 260 260 number d = n_GetDenom(p_GetCoeff(p, currRing), currRing); 261 if (!n_IsOne (d, currRing->cf)) WarnS("ignoring denominators of coefficients..."); 261 if (!n_IsOne (d, currRing->cf)) 262 WarnS("ignoring denominators of coefficients..."); 262 263 n_Delete(&d, currRing); 263 264 -
libpolys/coeffs/Enumerator.h
r9f6cc0 rdc79bd 54 54 virtual void Reset() = 0; 55 55 56 virtual ~IBaseEnumerator() {} // TODO: needed? 57 56 /// Current position is inside the collection (not -1 or past the end) 57 virtual bool IsValid() const = 0; 58 58 59 private: 60 /// disable copy constructor and assigment operator 59 61 IBaseEnumerator(const IBaseEnumerator&); 60 62 void operator=(const IBaseEnumerator&); … … 62 64 protected: 63 65 IBaseEnumerator(){} 64 65 /// Current position is inside the collection (not -1 or past the end) 66 virtual bool IsValid() const = 0; 66 ~IBaseEnumerator() {} // TODO: needed? 67 68 67 69 }; 68 70 … … 90 92 virtual const_reference Current() const = 0; 91 93 92 virtual ~IAccessor() {} // TODO: needed? 94 protected: 95 IAccessor(){} 96 ~IAccessor() {} // TODO: needed? 93 97 94 98 }; -
libpolys/coeffs/coeffs.h
r9f6cc0 rdc79bd 774 774 { 775 775 assume(r != NULL); 776 return ((!nCoeff_is_Ring(r)) && (n_GetChar(r) == 0) && nCoeff_is_Extension(r)); 777 } 776 return ((n_GetChar(r) == 0) && nCoeff_is_Extension(r)); 777 } 778 779 780 778 781 779 782 static inline BOOLEAN nCoeff_is_long_R(const coeffs r) … … 798 801 static inline BOOLEAN nCoeff_is_algExt(const coeffs r) 799 802 { assume(r != NULL); return (getCoeffType(r)==n_algExt); } 803 804 /// is it an alg. ext. of Q? 805 static inline BOOLEAN nCoeff_is_Q_algext(const coeffs r) 806 { assume(r != NULL); return ((n_GetChar(r) == 0) && nCoeff_is_algExt(r)); } 800 807 801 808 /// TRUE iff r represents a transcendental extension field -
libpolys/coeffs/longrat.cc
r9f6cc0 rdc79bd 2641 2641 } 2642 2642 2643 staticvoid nlClearContent(ICoeffsEnumerator& numberCollectionEnumerator, number& c, const coeffs cf)2643 void nlClearContent(ICoeffsEnumerator& numberCollectionEnumerator, number& c, const coeffs cf) 2644 2644 { 2645 2645 assume(cf != NULL); … … 2661 2661 s=2147483647; // max. int 2662 2662 2663 2664 int lc_is_pos=nlGreaterZero(numberCollectionEnumerator.Current(),cf); 2663 const BOOLEAN lc_is_pos=nlGreaterZero(numberCollectionEnumerator.Current(),cf); 2665 2664 2666 2665 int normalcount = 0; … … 2735 2734 } 2736 2735 2737 static void nlClearDenominators(ICoeffsEnumerator& numberCollectionEnumerator, number& c, const coeffs cf) 2736 void nlClearContentNoPositiveLead(ICoeffsEnumerator& numberCollectionEnumerator, number& c, const coeffs cf) 2737 { 2738 assume(cf != NULL); 2739 assume(getCoeffType(cf) == ID); 2740 2741 numberCollectionEnumerator.Reset(); 2742 2743 if( !numberCollectionEnumerator.MoveNext() ) // empty zero polynomial? 2744 { 2745 c = n_Init(1, cf); 2746 return; 2747 } 2748 2749 // all coeffs are given by integers!!! 2750 2751 // part 1, find a small candidate for gcd 2752 number cand1,cand; 2753 int s1,s; 2754 s=2147483647; // max. int 2755 2756 const BOOLEAN lc_is_pos = TRUE; // nlGreaterZero(numberCollectionEnumerator.Current(),cf); 2757 2758 int normalcount = 0; 2759 do 2760 { 2761 number& n = numberCollectionEnumerator.Current(); 2762 nlNormalize(n, cf); ++normalcount; 2763 cand1 = n; 2764 2765 if (SR_HDL(cand1)&SR_INT) { cand=cand1; break; } 2766 assume(cand1->s==3); // all coeffs should be integers // ==0?!! after printing 2767 s1=mpz_size1(cand1->z); 2768 if (s>s1) 2769 { 2770 cand=cand1; 2771 s=s1; 2772 } 2773 } while (numberCollectionEnumerator.MoveNext() ); 2774 2775 // assume( nlGreaterZero(cand,cf) ); // cand may be a negative integer! 2776 2777 cand=nlCopy(cand,cf); 2778 // part 2: compute gcd(cand,all coeffs) 2779 2780 numberCollectionEnumerator.Reset(); 2781 2782 while (numberCollectionEnumerator.MoveNext() ) 2783 { 2784 number& n = numberCollectionEnumerator.Current(); 2785 2786 if( (--normalcount) <= 0) 2787 nlNormalize(n, cf); 2788 2789 nlInpGcd(cand, n, cf); 2790 2791 assume( nlGreaterZero(cand,cf) ); 2792 2793 if(nlIsOne(cand,cf)) 2794 { 2795 c = cand; 2796 2797 if(!lc_is_pos) 2798 { 2799 // make the leading coeff positive 2800 c = nlNeg(c, cf); 2801 numberCollectionEnumerator.Reset(); 2802 2803 while (numberCollectionEnumerator.MoveNext() ) 2804 { 2805 number& nn = numberCollectionEnumerator.Current(); 2806 nn = nlNeg(nn, cf); 2807 } 2808 } 2809 return; 2810 } 2811 } 2812 2813 // part3: all coeffs = all coeffs / cand 2814 if (!lc_is_pos) 2815 cand = nlNeg(cand,cf); 2816 2817 c = cand; 2818 numberCollectionEnumerator.Reset(); 2819 2820 while (numberCollectionEnumerator.MoveNext() ) 2821 { 2822 number& n = numberCollectionEnumerator.Current(); 2823 number t=nlIntDiv(n, cand, cf); // simple integer exact division, no ratios to remain 2824 nlDelete(&n, cf); 2825 n = t; 2826 } 2827 } 2828 2829 void nlClearDenominators(ICoeffsEnumerator& numberCollectionEnumerator, number& c, const coeffs cf) 2738 2830 { 2739 2831 assume(cf != NULL); … … 2745 2837 { 2746 2838 c = n_Init(1, cf); 2839 // assume( n_GreaterZero(c, cf) ); 2747 2840 return; 2748 2841 } … … 2759 2852 2760 2853 int s=0; 2761 // mpz_t tmp; mpz_init(tmp); // tmp = GMP int2762 2854 2763 intlc_is_pos=nlGreaterZero(numberCollectionEnumerator.Current(),cf);2855 const BOOLEAN lc_is_pos=nlGreaterZero(numberCollectionEnumerator.Current(),cf); 2764 2856 2765 2857 do … … 2781 2873 { 2782 2874 mpz_lcm(cand->z, cand->z, cand1->n); 2783 /*2784 mpz_gcd(tmp,cand->z,cand1->n); // tmp = GCD( cand->z, cand1->n )2785 2786 if (mpz_cmp_si(tmp,1)!=0)2787 mpz_divexact(cand->z,cand->z,tmp); // cand->z /= tmp2788 2789 mpz_mul(cand->z,cand->z,cand1->n); // cand->z *= cand1->n2790 */2791 2875 } 2792 2876 } … … 2815 2899 } 2816 2900 } 2901 // assume( n_GreaterZero(c, cf) ); 2817 2902 return; 2818 2903 } … … 2829 2914 c = cand; 2830 2915 2916 while (numberCollectionEnumerator.MoveNext() ) 2917 { 2918 number &n = numberCollectionEnumerator.Current(); 2919 n_InpMult(n, cand, cf); 2920 } 2921 2922 } 2923 2924 2925 void nlClearDenominatorsNoPositiveLead(ICoeffsEnumerator& numberCollectionEnumerator, number& c, const coeffs cf) 2926 { 2927 assume(cf != NULL); 2928 assume(getCoeffType(cf) == ID); 2929 2930 numberCollectionEnumerator.Reset(); 2931 2932 if( !numberCollectionEnumerator.MoveNext() ) // empty zero polynomial? 2933 { 2934 c = n_Init(1, cf); 2935 return; 2936 } 2937 2938 // all coeffs are given by integers after returning from this routine 2939 2940 // part 1, collect product of all denominators /gcds 2941 number cand; 2942 cand=ALLOC_RNUMBER(); 2943 #if defined(LDEBUG) 2944 cand->debug=123456; 2945 #endif 2946 cand->s=3; 2947 2948 int s=0; 2949 2950 const BOOLEAN lc_is_pos = TRUE; // nlGreaterZero(numberCollectionEnumerator.Current(),cf); 2951 2952 do 2953 { 2954 number& cand1 = numberCollectionEnumerator.Current(); 2955 2956 if (!(SR_HDL(cand1)&SR_INT)) 2957 { 2958 nlNormalize(cand1, cf); 2959 if ((!(SR_HDL(cand1)&SR_INT)) // not a short int 2960 && (cand1->s==1)) // and is a normalised rational 2961 { 2962 if (s==0) // first denom, we meet 2963 { 2964 mpz_init_set(cand->z, cand1->n); // cand->z = cand1->n 2965 s=1; 2966 } 2967 else // we have already something 2968 { 2969 mpz_lcm(cand->z, cand->z, cand1->n); 2970 } 2971 } 2972 } 2973 } 2974 while (numberCollectionEnumerator.MoveNext() ); 2975 2976 2977 if (s==0) // nothing to do, all coeffs are already integers 2978 { 2979 // mpz_clear(tmp); 2980 FREE_RNUMBER(cand); 2981 if (lc_is_pos) 2982 c=nlInit(1,cf); 2983 else 2984 { 2985 // make the leading coeff positive 2986 c=nlInit(-1,cf); 2987 2988 // TODO: incorporate the following into the loop below? 2989 numberCollectionEnumerator.Reset(); 2990 while (numberCollectionEnumerator.MoveNext() ) 2991 { 2992 number& n = numberCollectionEnumerator.Current(); 2993 n = nlNeg(n, cf); 2994 } 2995 } 2996 return; 2997 } 2998 2999 cand = nlShort3(cand); 3000 3001 // part2: all coeffs = all coeffs * cand 3002 // make the lead coeff positive 3003 numberCollectionEnumerator.Reset(); 3004 3005 if (!lc_is_pos) 3006 cand = nlNeg(cand, cf); 3007 3008 c = cand; 3009 2831 3010 while (numberCollectionEnumerator.MoveNext() ) 2832 3011 { -
libpolys/coeffs/numbers.cc
r9f6cc0 rdc79bd 129 129 130 130 // no fractions 131 assume(!( nCoeff_is_Q(r) || nCoeff_is_Q_a(r)));131 assume(!( nCoeff_is_Q(r) )); 132 132 // all coeffs are given by integers!!! 133 133 … … 172 172 173 173 assume(!nCoeff_is_Ring(r)); 174 assume(nCoeff_is_Zp(r) || nCoeff_is_numeric(r) || nCoeff_is_GF(r) || nCoeff_is_Zp_a(r) );175 176 c = curr;177 178 n_Normalize(c, r);179 180 if (!n_IsOne(c, r))181 { 174 assume(nCoeff_is_Zp(r) || nCoeff_is_numeric(r) || nCoeff_is_GF(r) || nCoeff_is_Zp_a(r) || nCoeff_is_Q_algext(r)); 175 176 n_Normalize(curr, r); // Q: good/bad/ugly?? 177 178 if (!n_IsOne(curr, r)) 179 { 180 number t = curr; // takes over the curr! note: not a reference!!! 181 182 182 curr = n_Init(1, r); // ??? 183 183 184 number inv = n_Invers( c, r);184 number inv = n_Invers(t, r); 185 185 186 186 while( numberCollectionEnumerator.MoveNext() ) 187 187 { 188 188 number &n = numberCollectionEnumerator.Current(); 189 n_Normalize(n, r); // ?190 189 n_InpMult(n, inv, r); // TODO: either this or directly divide!!!? 190 // n_Normalize(n, r); // ? 191 191 } 192 192 193 193 n_Delete(&inv, r); 194 } 194 195 c = t; 196 } else 197 c = n_Copy(curr, r); // c == 1 and nothing else to do... 195 198 } 196 199 -
libpolys/polys/PolyEnumerator.h
r9f6cc0 rdc79bd 33 33 class CBasePolyEnumerator: public virtual IBaseEnumerator 34 34 { 35 template <class T> 36 friend class CRecursivePolyCoeffsEnumerator; 35 37 private: 36 constpoly m_poly; ///< essentially immutable original iterable object38 poly m_poly; ///< essentially immutable original iterable object 37 39 38 40 static const spolyrec m_prevposition_struct; ///< tag for "-1" position … … 41 43 poly m_position; ///< current position in the iterable object 42 44 45 public: 43 46 virtual bool IsValid() const 44 47 { … … 46 49 return (m_position != NULL) && (m_position != &m_prevposition_struct); 47 50 } 48 49 public: 50 CBasePolyEnumerator(poly p): 51 52 53 /// Reset this polynomial Enumerator with a different input polynomial 54 void Reset(poly p) 55 { 56 m_poly = p; 57 m_position = const_cast<poly>(&m_prevposition_struct); 58 assume( !IsValid() ); 59 } 60 61 /// This enumerator is an empty polynomial by default 62 CBasePolyEnumerator(poly p = NULL): 51 63 IBaseEnumerator(), m_poly(p), m_position(const_cast<poly>(&m_prevposition_struct)) 52 64 { … … 60 72 assume( !IsValid() ); 61 73 } 74 62 75 63 76 /// Advances the position to the next term of the polynomial. … … 117 130 { 118 131 public: 119 CPolyCoeffsEnumerator(poly p): CBasePolyEnumerator(p) { assume(p != NULL);}132 CPolyCoeffsEnumerator(poly p): CBasePolyEnumerator(p) {} 120 133 121 134 /// Gets the current element in the collection (read and write). … … 134 147 }; 135 148 149 150 struct NAConverter 151 { 152 static inline poly convert(const number& n) 153 { 154 // suitable for alg. ext. numbers that are just polys actually 155 return (poly)n; 156 } 157 }; 158 159 /// go into polynomials over an alg. extension recursively 160 template <class ConverterPolicy> 161 class CRecursivePolyCoeffsEnumerator: public IPolyCoeffsEnumerator 162 { 163 private: 164 IPolyCoeffsEnumerator& m_global_enumerator; ///< iterates the input polynomial 165 CBasePolyEnumerator m_local_enumerator; ///< iterates the current coeff. of m_global_enumerator 166 167 protected: 168 virtual bool IsValid() const 169 { 170 return m_global_enumerator.IsValid() && m_local_enumerator.IsValid(); 171 } 172 173 public: 174 175 /// NOTE: carefull: don't destruct the input enumerator before doing it with this one... 176 /// this also changes the original IPolyCoeffsEnumerator& itr! 177 CRecursivePolyCoeffsEnumerator(IPolyCoeffsEnumerator& itr): m_global_enumerator(itr), m_local_enumerator(NULL) {} 178 179 virtual bool MoveNext() 180 { 181 if( m_local_enumerator.MoveNext() ) 182 return true; 183 184 if( !m_global_enumerator.MoveNext() ) // at the end of the main input polynomial? 185 return false; 186 187 // TODO: make the following changeable (metaprogramming: use policy?), 188 // leave the following as default option... 189 poly p = ConverterPolicy::convert(m_global_enumerator.Current()); // Assumes that these numbers are just polynomials! 190 assume( p != NULL ); 191 192 // the followig actually needs CPolyCoeffsEnumerator 193 m_local_enumerator.Reset( p ); // -1 position in p :: to be skipped now! 194 195 if( m_local_enumerator.MoveNext() ) // should be true 196 return true; 197 198 assume( FALSE ); return MoveNext(); // this should not happen as p should be non-zero, but just in case... 199 } 200 201 virtual void Reset() 202 { 203 m_global_enumerator.Reset(); 204 m_local_enumerator.Reset(NULL); 205 } 206 207 /// Gets the current element in the collection (read and write). 208 virtual IPolyCoeffsEnumerator::reference Current() 209 { 210 assume( IsValid() ); 211 return pGetCoeff(m_local_enumerator.m_position); 212 } 213 214 /// Gets the current element in the collection (read only). 215 virtual IPolyCoeffsEnumerator::const_reference Current() const 216 { 217 assume( IsValid() ); 218 return pGetCoeff(m_local_enumerator.m_position); 219 } 220 }; 221 222 136 223 #endif 137 224 /* #ifndef POLYENUMERATOR_H */ -
libpolys/polys/clapsing.h
r9f6cc0 rdc79bd 23 23 //#include <kernel/longtrans.h> 24 24 25 / * destroys f and g */25 /// destroys f and g 26 26 poly singclap_gcd ( poly f, poly g, const ring r ); 27 27 28 /* 28 29 29 // commented out! 30 napoly singclap_alglcm ( napoly f, napoly g ); 31 void singclap_algdividecontent ( napoly f, napoly g, napoly &ff, napoly &gg ); 32 */ 30 // poly singclap_alglcm ( poly f, poly g, const ring r ); 31 // void singclap_algdividecontent ( napoly f, napoly g, napoly &ff, napoly &gg ); 33 32 34 33 poly singclap_resultant ( poly f, poly g , poly x, const ring r); -
libpolys/polys/ext_fields/algext.cc
r9f6cc0 rdc79bd 44 44 #include <polys/simpleideals.h> 45 45 46 #include <polys/PolyEnumerator.h> 47 46 48 #ifdef HAVE_FACTORY 49 #include <factory/factory.h> 47 50 #include <polys/clapconv.h> 48 #include < factory/factory.h>51 #include <polys/clapsing.h> 49 52 #endif 50 53 51 #include "ext_fields/algext.h" 54 55 #include <polys/ext_fields/algext.h> 52 56 #define TRANSEXT_PRIVATES 1 53 #include "ext_fields/transext.h"57 #include <polys/ext_fields/transext.h> 54 58 55 59 #ifdef LDEBUG … … 103 107 void naDelete(number *a, const coeffs cf); 104 108 void naCoeffWrite(const coeffs cf, BOOLEAN details); 105 number naIntDiv(number a, number b, const coeffs cf);109 //number naIntDiv(number a, number b, const coeffs cf); 106 110 const char * naRead(const char *s, number *a, const coeffs cf); 107 111 … … 652 656 naTest(a); naTest(b); 653 657 if ((a == NULL) && (b == NULL)) WerrorS(nDivBy0); 654 return (number)p_Gcd((poly)a, (poly)b, naRing); 658 const ring R = naRing; 659 return (number) singclap_gcd(p_Copy((poly)a, R), p_Copy((poly)b, R), R); 660 // return (number)p_Gcd((poly)a, (poly)b, naRing); 655 661 } 656 662 … … 660 666 if (a == NULL) WerrorS(nDivBy0); 661 667 662 poly aFactor = NULL; poly mFactor = NULL; 663 poly theGcd = p_ExtGcd((poly)a, aFactor, naMinpoly, mFactor, naRing); 668 poly aFactor = NULL; poly mFactor = NULL; poly theGcd = NULL; 669 // singclap_extgcd! 670 const BOOLEAN ret = singclap_extgcd ((poly)a, naMinpoly, theGcd, aFactor, mFactor, naRing); 671 672 assume( !ret ); 673 674 // if( ret ) theGcd = p_ExtGcd((poly)a, aFactor, naMinpoly, mFactor, naRing); 664 675 665 676 naTest((number)theGcd); naTest((number)aFactor); naTest((number)mFactor); … … 845 856 } 846 857 847 static void naClearContent(ICoeffsEnumerator& /*numberCollectionEnumerator*/, number& c, const coeffs cf) 858 859 static void naClearContent(ICoeffsEnumerator& numberCollectionEnumerator, number& c, const coeffs cf) 848 860 { 849 861 assume(cf != NULL); 850 862 assume(getCoeffType(cf) == ID); 851 assume(nCoeff_is_Q_a(cf)); // only over Q[a]/m(a), while the default impl. is used over Zp[a]/m(a) ! 852 // all coeffs are given by integers!!! 853 854 c = n_Init(1, cf); 855 assume(FALSE); // TODO: NOT YET IMPLEMENTED!!! 856 857 // numberCollectionEnumerator.Reset(); 858 // 859 // c = numberCollectionEnumerator.Current(); 860 // 861 // n_Normalize(c, r); 862 // 863 // if (!n_IsOne(c, r)) 864 // { 865 // numberCollectionEnumerator.Current() = n_Init(1, r); // ??? 866 // 867 // number inv = n_Invers(c, r); 868 // 869 // while( numberCollectionEnumerator.MoveNext() ) 870 // { 871 // number &n = numberCollectionEnumerator.Current(); 872 // n_Normalize(n, r); // ? 873 // n_InpMult(n, inv, r); 874 // } 875 // 876 // n_Delete(&inv, r); 877 // } 863 assume(nCoeff_is_Q_algext(cf)); // only over (Q[a]/m(a)), while the default impl. is used over Zp[a]/m(a) ! 864 865 const ring R = cf->extRing; 866 assume(R != NULL); 867 const coeffs Q = R->cf; 868 assume(Q != NULL); 869 assume(nCoeff_is_Q(Q)); 870 871 numberCollectionEnumerator.Reset(); 872 873 if( !numberCollectionEnumerator.MoveNext() ) // empty zero polynomial? 874 { 875 c = n_Init(1, cf); 876 return; 877 } 878 879 naTest(numberCollectionEnumerator.Current()); 880 881 // part 1, find a small candidate for gcd 882 int s1; int s=2147483647; // max. int 883 884 const BOOLEAN lc_is_pos=naGreaterZero(numberCollectionEnumerator.Current(),cf); 885 886 int normalcount = 0; 887 888 poly cand1, cand; 889 890 do 891 { 892 number& n = numberCollectionEnumerator.Current(); 893 naNormalize(n, cf); ++normalcount; 894 895 naTest(n); 896 897 cand1 = (poly)n; 898 899 s1 = p_Deg(cand1, R); // naSize? 900 if (s>s1) 901 { 902 cand = cand1; 903 s = s1; 904 } 905 } while (numberCollectionEnumerator.MoveNext() ); 906 907 // assume( nlGreaterZero(cand,cf) ); // cand may be a negative integer! 908 909 cand = p_Copy(cand, R); 910 // part 2: compute gcd(cand,all coeffs) 911 912 numberCollectionEnumerator.Reset(); 913 914 int length = 0; 915 while (numberCollectionEnumerator.MoveNext() ) 916 { 917 number& n = numberCollectionEnumerator.Current(); 918 ++length; 919 920 if( (--normalcount) <= 0) 921 naNormalize(n, cf); 922 923 naTest(n); 924 925 // p_InpGcd(cand, (poly)n, R); 926 927 cand = singclap_gcd(cand, p_Copy((poly)n, R), R); 928 929 // cand1 = p_Gcd(cand,(poly)n, R); p_Delete(&cand, R); cand = cand1; 930 931 assume( naGreaterZero((number)cand, cf) ); // ??? 932 /* 933 if(p_IsConstant(cand,R)) 934 { 935 c = cand; 936 937 if(!lc_is_pos) 938 { 939 // make the leading coeff positive 940 c = nlNeg(c, cf); 941 numberCollectionEnumerator.Reset(); 942 943 while (numberCollectionEnumerator.MoveNext() ) 944 { 945 number& nn = numberCollectionEnumerator.Current(); 946 nn = nlNeg(nn, cf); 947 } 948 } 949 return; 950 } 951 */ 952 953 } 954 955 // part3: all coeffs = all coeffs / cand 956 if (!lc_is_pos) 957 cand = p_Neg(cand, R); 958 959 c = (number)cand; naTest(c); 960 961 poly cInverse = (poly)naInvers(c, cf); 962 assume(cInverse != NULL); // c is non-zero divisor!? 963 964 965 numberCollectionEnumerator.Reset(); 966 967 968 while (numberCollectionEnumerator.MoveNext() ) 969 { 970 number& n = numberCollectionEnumerator.Current(); 971 972 assume( length > 0 ); 973 974 if( --length > 0 ) 975 { 976 assume( cInverse != NULL ); 977 n = (number) p_Mult_q(p_Copy(cInverse, R), (poly)n, R); 978 } 979 else 980 { 981 n = (number) p_Mult_q(cInverse, (poly)n, R); 982 cInverse = NULL; 983 assume(length == 0); 984 } 985 986 definiteReduce((poly &)n, naMinpoly, cf); 987 } 988 989 assume(length == 0); 990 assume(cInverse == NULL); // p_Delete(&cInverse, R); 991 992 // Quick and dirty fix for constant content clearing... !? 993 CRecursivePolyCoeffsEnumerator<NAConverter> itr(numberCollectionEnumerator); // recursively treat the numbers as polys! 994 995 number cc; 996 997 extern void nlClearContentNoPositiveLead(ICoeffsEnumerator&, number&, const coeffs); 998 999 nlClearContentNoPositiveLead(itr, cc, Q); // TODO: get rid of (-LC) normalization!? 1000 1001 // over alg. ext. of Q // takes over the input number 1002 c = (number) p_Mult_nn( (poly)c, cc, R); 1003 // p_Mult_q(p_NSet(cc, R), , R); 1004 1005 n_Delete(&cc, Q); 1006 1007 // TODO: the above is not enough! need GCD's of polynomial coeffs...! 1008 /* 1009 // old and wrong part of p_Content 1010 if (rField_is_Q_a(r) && !CLEARENUMERATORS) // should not be used anymore if CLEARENUMERATORS is 1 1011 { 1012 // we only need special handling for alg. ext. 1013 if (getCoeffType(r->cf)==n_algExt) 1014 { 1015 number hzz = n_Init(1, r->cf->extRing->cf); 1016 p=ph; 1017 while (p!=NULL) 1018 { // each monom: coeff in Q_a 1019 poly c_n_n=(poly)pGetCoeff(p); 1020 poly c_n=c_n_n; 1021 while (c_n!=NULL) 1022 { // each monom: coeff in Q 1023 d=n_Lcm(hzz,pGetCoeff(c_n),r->cf->extRing->cf); 1024 n_Delete(&hzz,r->cf->extRing->cf); 1025 hzz=d; 1026 pIter(c_n); 1027 } 1028 pIter(p); 1029 } 1030 // hzz contains the 1/lcm of all denominators in c_n_n 1031 h=n_Invers(hzz,r->cf->extRing->cf); 1032 n_Delete(&hzz,r->cf->extRing->cf); 1033 n_Normalize(h,r->cf->extRing->cf); 1034 if(!n_IsOne(h,r->cf->extRing->cf)) 1035 { 1036 p=ph; 1037 while (p!=NULL) 1038 { // each monom: coeff in Q_a 1039 poly c_n=(poly)pGetCoeff(p); 1040 while (c_n!=NULL) 1041 { // each monom: coeff in Q 1042 d=n_Mult(h,pGetCoeff(c_n),r->cf->extRing->cf); 1043 n_Normalize(d,r->cf->extRing->cf); 1044 n_Delete(&pGetCoeff(c_n),r->cf->extRing->cf); 1045 pGetCoeff(c_n)=d; 1046 pIter(c_n); 1047 } 1048 pIter(p); 1049 } 1050 } 1051 n_Delete(&h,r->cf->extRing->cf); 1052 } 1053 } 1054 */ 1055 1056 1057 // c = n_Init(1, cf); assume(FALSE); // TODO: NOT YET IMPLEMENTED!!! 1058 } 1059 1060 1061 static void naClearDenominators(ICoeffsEnumerator& numberCollectionEnumerator, number& c, const coeffs cf) 1062 { 1063 assume(cf != NULL); 1064 assume(getCoeffType(cf) == ID); 1065 assume(nCoeff_is_Q_algext(cf)); // only over (Q[a]/m(a)), while the default impl. is used over Zp[a]/m(a) ! 1066 1067 assume(cf->extRing != NULL); 1068 const coeffs Q = cf->extRing->cf; 1069 assume(Q != NULL); 1070 assume(nCoeff_is_Q(Q)); 1071 number n; 1072 CRecursivePolyCoeffsEnumerator<NAConverter> itr(numberCollectionEnumerator); // recursively treat the numbers as polys! 1073 1074 extern void nlClearDenominatorsNoPositiveLead(ICoeffsEnumerator&, number&, const coeffs); 1075 1076 nlClearDenominatorsNoPositiveLead(itr, n, Q); // this should probably be fine... 1077 c = (number)p_NSet(n, cf->extRing); // over alg. ext. of Q // takes over the input number 878 1078 } 879 1079 … … 951 1151 cf->nCoeffIsEqual = naCoeffIsEqual; 952 1152 cf->cfInvers = naInvers; 953 cf->cfIntDiv = naDiv; 1153 cf->cfIntDiv = naDiv; // ??? 954 1154 #ifdef HAVE_FACTORY 955 1155 cf->convFactoryNSingN=naConvFactoryNSingN; … … 963 1163 964 1164 if( nCoeff_is_Q(R->cf) ) 1165 { 965 1166 cf->cfClearContent = naClearContent; 1167 cf->cfClearDenominators = naClearDenominators; 1168 } 966 1169 967 1170 return FALSE; -
libpolys/polys/ext_fields/transext.cc
r9f6cc0 rdc79bd 30 30 * is being replaced by a quotient of two polynomials over Z, or 31 31 * - if the denominator is a constant - by a polynomial over Q. 32 * 33 * TODO: the description above needs a major update!!! 32 34 */ 33 35 #define TRANSEXT_PRIVATES … … 54 56 #endif 55 57 56 #include "ext_fields/transext.h" 57 #include "prCopy.h" 58 #include <polys/ext_fields/transext.h> 59 #include <polys/prCopy.h> 60 61 #include <polys/PolyEnumerator.h> 62 58 63 59 64 /* constants for controlling the complexity of numbers */ … … 62 67 #define BOUND_COMPLEXITY 10 /**< maximum complexity of a number */ 63 68 64 #define NUMIS1(f) (p_IsConstant(NUM(f), cf->extRing) && \ 65 n_IsOne(p_GetCoeff(NUM(f), cf->extRing), \ 66 cf->extRing->cf)) 67 /**< TRUE iff num. represents 1 */ 69 70 static inline BOOLEAN p_IsOne(const poly p, const ring R) 71 { 72 assume( p_Test(p, R) ); 73 return (p_IsConstant(p, R) && n_IsOne(p_GetCoeff(p, R), R->cf)); 74 } 75 76 /// TRUE iff num. represents 1 77 #define NUMIS1(f) (p_IsOne(NUM(f), cf->extRing)) 78 68 79 #define COM(f) f->complexity 69 80 70 81 71 82 #ifdef LDEBUG 72 #define ntTest(a) ntDBTest(a,__FILE__,__LINE__,cf)83 #define ntTest(a) assume(ntDBTest(a,__FILE__,__LINE__,cf)) 73 84 BOOLEAN ntDBTest(number a, const char *f, const int l, const coeffs r); 74 85 #else … … 89 100 #define ntCoeffs cf->extRing->cf 90 101 102 103 extern void nlClearContent(ICoeffsEnumerator&, number&, const coeffs); 104 extern void nlClearContentNoPositiveLead(ICoeffsEnumerator&, number&, const coeffs); 105 106 //extern void nlClearDenominators(ICoeffsEnumerator&, number&, const coeffs); 107 //extern void nlClearDenominatorsNoPositiveLead(ICoeffsEnumerator&, number&, const coeffs); 91 108 92 109 … … 134 151 { 135 152 assume(getCoeffType(cf) == ID); 136 fraction t = (fraction)a; 137 if (IS0(t)) return TRUE; 138 assume(NUM(t) != NULL); /**< t != 0 ==> numerator(t) != 0 */ 139 p_Test(NUM(t), ntRing); 140 if (!DENIS1(t)) 141 { 142 p_Test(DEN(t), ntRing); 143 if(p_IsConstant(DEN(t),ntRing) && (n_IsOne(pGetCoeff(DEN(t)),ntRing->cf))) 153 154 if (IS0(a)) return TRUE; 155 156 const fraction t = (fraction)a; 157 158 const poly num = NUM(t); 159 assume(num != NULL); /**< t != 0 ==> numerator(t) != 0 */ 160 assume( p_Test(num, ntRing) ); 161 162 const poly den = DEN(t); 163 164 if (den != NULL) // !DENIS1(f) 165 { 166 assume( p_Test(den, ntRing) ); 167 168 if(p_IsConstant(den, ntRing) && (n_IsOne(pGetCoeff(den), ntRing->cf))) 144 169 { 145 170 Print("?/1 in %s:%d\n",f,l); 146 return FALSE; 147 } 171 return FALSE; 172 } 173 174 if( !n_GreaterZero(pGetCoeff(den), ntRing->cf) ) 175 { 176 Print("negative sign of DEN. of a fraction in %s:%d\n",f,l); 177 return FALSE; 178 } 179 180 // test that den is over integers!? 181 182 } else 183 { // num != NULL // den == NULL 184 185 // if( COM(t) != 0 ) 186 // { 187 // Print("?//NULL with non-zero complexity: %d in %s:%d\n", COM(t), f, l); 188 // return FALSE; 189 // } 190 // test that nume is over integers!? 148 191 } 149 192 return TRUE; … … 171 214 BOOLEAN ntIsZero(number a, const coeffs cf) 172 215 { 173 ntTest(a); 216 ntTest(a); // !!! 174 217 return (IS0(a)); 175 218 } … … 177 220 void ntDelete(number * a, const coeffs cf) 178 221 { 222 ntTest(*a); // !!! 179 223 fraction f = (fraction)(*a); 180 224 if (IS0(f)) return; … … 187 231 BOOLEAN ntEqual(number a, number b, const coeffs cf) 188 232 { 189 ntTest(a); ntTest(b); 233 ntTest(a); 234 ntTest(b); 190 235 191 236 /// simple tests … … 230 275 number ntCopy(number a, const coeffs cf) 231 276 { 232 ntTest(a); 277 ntTest(a); // !!! 233 278 if (IS0(a)) return NULL; 234 279 fraction f = (fraction)a; … … 239 284 DEN(result) = h; 240 285 COM(result) = COM(f); 286 ntTest((number)result); 241 287 return (number)result; 242 288 } 243 289 290 /// TODO: normalization of a!? 244 291 number ntGetNumerator(number &a, const coeffs cf) 245 292 { 246 293 ntTest(a); 247 294 definiteGcdCancellation(a, cf, FALSE); 295 248 296 if (IS0(a)) return NULL; 297 249 298 fraction f = (fraction)a; 250 299 fraction result = (fraction)omAlloc0Bin(fractionObjectBin); 251 BOOLEAN denis1= DENIS1 (f); 300 301 const BOOLEAN denis1= DENIS1 (f); 302 252 303 if (getCoeffType (ntCoeffs) == n_Q && !denis1) 253 304 handleNestedFractionsOverQ (f, cf); 254 NUM (result)= p_Copy (NUM (f), ntRing); 305 306 if (getCoeffType (ntCoeffs) == n_Q && denis1) 307 { 308 assume( DEN (f) == NULL ); 309 310 number g; 311 // TODO/NOTE: the following should not be necessary (due to 312 // Hannes!) as NUM (f) should be over Z!!! 313 CPolyCoeffsEnumerator itr(NUM(f)); 314 315 316 n_ClearDenominators(itr, g, ntRing->cf); 317 // nlClearDenominators(itr, g, ntRing->cf); 318 319 if( !n_GreaterZero(g, ntRing->cf) ) 320 { 321 NUM (f) = p_Neg(NUM (f), ntRing); // Ugly :((( 322 g = n_Neg(g, ntRing->cf); 323 } 324 325 // g should be a positive integer now! 326 assume( n_GreaterZero(g, ntRing->cf) ); 327 328 if( !n_IsOne(g, ntRing->cf) ) 329 { 330 DEN (f) = p_NSet(g, ntRing); // update COM(f)??? 331 COM (f) ++; 332 assume( DEN (f) != NULL ); 333 } 334 else 335 n_Delete(&g, ntRing->cf); 336 337 ntTest(a); 338 } 339 340 // Call ntNormalize instead of above?!? 341 342 NUM (result) = p_Copy (NUM (f), ntRing); // ??? 255 343 DEN (result) = NULL; 256 344 COM (result) = 0; 257 if (getCoeffType (ntCoeffs) == n_Q && denis1) 258 { 259 if (!p_IsConstant (NUM (result), ntRing) && pNext (NUM(result)) != NULL) 260 p_Cleardenom (NUM(result), ntRing); 261 else 262 { 263 number g= p_GetAllDenom (NUM (result), ntRing); 264 NUM (result)= p_Mult_nn (NUM (result), g, ntRing); 265 } 266 } 345 346 ntTest((number)result); 267 347 return (number)result; 268 348 } 269 349 350 /// TODO: normalization of a!? 270 351 number ntGetDenom(number &a, const coeffs cf) 271 352 { … … 273 354 definiteGcdCancellation(a, cf, FALSE); 274 355 fraction f = (fraction)a; 356 275 357 fraction result = (fraction)omAlloc0Bin(fractionObjectBin); 276 number g; 277 if (IS0(f) || (DENIS1 (f) && getCoeffType (ntCoeffs) != n_Q)) 358 DEN (result)= NULL; 359 COM (result)= 0; 360 361 362 const BOOLEAN denis1 = DENIS1 (f); 363 364 if( IS0(f) || (denis1 && getCoeffType (ntCoeffs) != n_Q) ) // */1 or 0 278 365 { 279 366 NUM (result)= p_One(ntRing); 280 DEN (result)= NULL; 281 COM (result)= 0; 282 } 283 else if (DENIS1 (f)) 284 { 285 poly num= p_Copy (NUM (f), ntRing); 286 if (!p_IsConstant (num, ntRing) && pNext(num) != NULL) 287 p_Cleardenom_n (num, ntRing, g); 288 else 289 g= p_GetAllDenom (num, ntRing); 290 result= (fraction) ntSetMap (ntRing->cf, cf) (g, ntRing->cf, cf); 291 } 292 else 293 { 367 ntTest((number)result); 368 return (number)result; 369 } 370 371 if (!denis1) // */* / Q 372 { 373 assume( DEN (f) != NULL ); 374 294 375 if (getCoeffType (ntCoeffs) == n_Q) 295 376 handleNestedFractionsOverQ (f, cf); 377 378 ntTest(a); 379 380 if( DEN (f) != NULL ) // is it ?? // 1 now??? 381 { 382 assume( !p_IsOne(DEN (f), ntRing) ); 383 384 NUM (result) = p_Copy (DEN (f), ntRing); 385 ntTest((number)result); 386 return (number)result; 387 } 388 // NUM (result) = p_One(ntRing); // NOTE: just in order to be sure... 389 } 390 391 // */1 / Q 392 assume( getCoeffType (ntCoeffs) == n_Q ); 393 assume( DEN (f) == NULL ); 394 395 number g; 396 // poly num= p_Copy (NUM (f), ntRing); // ??? 397 398 399 // TODO/NOTE: the following should not be necessary (due to 400 // Hannes!) as NUM (f) should be over Z!!! 401 CPolyCoeffsEnumerator itr(NUM(f)); 402 403 n_ClearDenominators(itr, g, ntRing->cf); // may return -1 :((( 404 // nlClearDenominators(itr, g, ntRing->cf); 405 406 407 if( !n_GreaterZero(g, ntRing->cf) ) 408 { 409 // NUM (f) = p_Neg(NUM (f), ntRing); // Ugly :((( 410 // g = n_Neg(g, ntRing->cf); 411 NUM (f) = p_Neg(NUM (f), ntRing); // Ugly :((( 412 g = n_Neg(g, ntRing->cf); 413 } 414 415 // g should be a positive integer now! 416 assume( n_GreaterZero(g, ntRing->cf) ); 417 418 if( !n_IsOne(g, ntRing->cf) ) 419 { 420 assume( n_GreaterZero(g, ntRing->cf) ); 421 assume( !n_IsOne(g, ntRing->cf) ); 422 423 DEN (f) = p_NSet(g, ntRing); // update COM(f)??? 424 assume( DEN (f) != NULL ); 425 COM (f) ++; 426 296 427 NUM (result)= p_Copy (DEN (f), ntRing); 297 DEN (result) = NULL; 298 COM (result) = 0; 299 } 428 } 429 else 430 { // common denom == 1? 431 NUM (result)= p_NSet(g, ntRing); // p_Copy (DEN (f), ntRing); 432 // n_Delete(&g, ntRing->cf); 433 } 434 435 // if (!p_IsConstant (num, ntRing) && pNext(num) != NULL) 436 // else 437 // g= p_GetAllDenom (num, ntRing); 438 // result= (fraction) ntSetMap (ntRing->cf, cf) (g, ntRing->cf, cf); 439 440 ntTest((number)result); 300 441 return (number)result; 301 442 } … … 303 444 BOOLEAN ntIsOne(number a, const coeffs cf) 304 445 { 305 ntTest(a); 446 ntTest(a); // !!! 306 447 definiteGcdCancellation(a, cf, FALSE); 307 448 fraction f = (fraction)a; … … 329 470 NUM(f) = p_Neg(NUM(f), ntRing); 330 471 } 472 ntTest(a); 331 473 return a; 332 474 } … … 359 501 360 502 fraction result = (fraction)omAlloc0Bin(fractionObjectBin); 361 362 NUM(result) = p_NSet(n, A); 363 DEN(result) = NULL; 503 504 number den = n_GetDenom(n, C); 505 506 assume( n_GreaterZero(den, C) ); 507 508 if( n_IsOne(den, C) ) 509 { 510 NUM(result) = p_NSet(n, A); 511 DEN(result) = NULL; 512 n_Delete(&den, C); 513 } else 514 { 515 DEN(result) = p_NSet(den, A); 516 NUM(result) = p_NSet(n_GetNumerator(n, C), A); 517 n_Delete(&n, C); 518 } 519 364 520 COM(result) = 0; 521 522 ntTest((number)result); 523 365 524 return (number)result; 366 525 } … … 376 535 //DEN(result) = NULL; // done by omAlloc0Bin 377 536 //COM(result) = 0; // done by omAlloc0Bin 537 ntTest((number)result); 378 538 return (number)result; 379 539 } 380 540 } 381 541 542 543 /// takes over p! 382 544 number ntInit(poly p, const coeffs cf) 383 545 { 384 546 if (p == 0) return NULL; 385 else 386 { 387 fraction result = (fraction)omAlloc0Bin(fractionObjectBin); 388 NUM(result) = p; 389 DEN(result) = NULL; 390 COM(result) = 0; 391 return (number)result; 392 } 547 548 number g; 549 // TODO/NOTE: the following should not be necessary (due to 550 // Hannes!) as NUM (f) should be over Z!!! 551 CPolyCoeffsEnumerator itr(p); 552 553 n_ClearDenominators(itr, g, ntRing->cf); 554 // nlClearDenominators(itr, g, ntRing->cf); 555 556 if( !n_GreaterZero(g, ntRing->cf) ) 557 { 558 p = p_Neg(p, ntRing); // Ugly :((( 559 g = n_Neg(g, ntRing->cf); 560 } 561 562 // g should be a positive integer now! 563 assume( n_GreaterZero(g, ntRing->cf) ); 564 565 fraction f = (fraction)omAlloc0Bin(fractionObjectBin); 566 567 if( !n_IsOne(g, ntRing->cf) ) 568 { 569 DEN (f) = p_NSet(g, ntRing); 570 // COM (f) ++; // update COM(f)??? 571 assume( DEN (f) != NULL ); 572 } 573 else 574 { 575 DEN(f) = NULL; 576 n_Delete(&g, ntRing->cf); 577 } 578 579 NUM(f) = p; 580 COM(f) = 0; 581 582 ntTest((number)f); 583 return (number)f; 393 584 } 394 585 … … 422 613 BOOLEAN ntGreater(number a, number b, const coeffs cf) 423 614 { 424 ntTest(a); ntTest(b); 615 ntTest(a); 616 ntTest(b); 425 617 number aNumCoeff = NULL; int aNumDeg = 0; 426 618 number bNumCoeff = NULL; int bNumDeg = 0; … … 497 689 number ntAdd(number a, number b, const coeffs cf) 498 690 { 499 ntTest(a); ntTest(b); 691 ntTest(a); 692 ntTest(b); 500 693 if (IS0(a)) return ntCopy(b, cf); 501 694 if (IS0(b)) return ntCopy(a, cf); … … 525 718 COM(result) = COM(fa) + COM(fb) + ADD_COMPLEXITY; 526 719 heuristicGcdCancellation((number)result, cf); 720 721 // ntTest((number)result); 722 527 723 return (number)result; 528 724 } … … 530 726 number ntSub(number a, number b, const coeffs cf) 531 727 { 532 ntTest(a); ntTest(b); 728 ntTest(a); 729 ntTest(b); 533 730 if (IS0(a)) return ntNeg(ntCopy(b, cf), cf); 534 731 if (IS0(b)) return ntCopy(a, cf); … … 558 755 COM(result) = COM(fa) + COM(fb) + ADD_COMPLEXITY; 559 756 heuristicGcdCancellation((number)result, cf); 757 // ntTest((number)result); 560 758 return (number)result; 561 759 } … … 563 761 number ntMult(number a, number b, const coeffs cf) 564 762 { 565 ntTest(a); ntTest(b); 763 ntTest(a); // !!!? 764 ntTest(b); // !!!? 765 566 766 if (IS0(a) || IS0(b)) return NULL; 567 767 … … 569 769 fraction fb = (fraction)b; 570 770 571 poly g = p_Copy(NUM(fa), ntRing); 572 poly h = p_Copy(NUM(fb), ntRing); 573 g = p_Mult_q(g, h, ntRing); 574 575 if (g == NULL) return NULL; /* may happen due to zero divisors */ 576 577 poly f; 578 if (DENIS1(fa) && DENIS1(fb)) f = NULL; 579 else if (!DENIS1(fa) && DENIS1(fb)) f = p_Copy(DEN(fa), ntRing); 580 else if (DENIS1(fa) && !DENIS1(fb)) f = p_Copy(DEN(fb), ntRing); 581 else /* both den's are != 1 */ f = p_Mult_q(p_Copy(DEN(fa), ntRing), 582 p_Copy(DEN(fb), ntRing), 583 ntRing); 771 const poly g = pp_Mult_qq(NUM(fa), NUM(fb), ntRing); 772 773 if (g == NULL) return NULL; // may happen due to zero divisors??? 584 774 585 775 fraction result = (fraction)omAlloc0Bin(fractionObjectBin); 776 586 777 NUM(result) = g; 587 DEN(result) = f; 588 COM(result) = COM(fa) + COM(fb) + MULT_COMPLEXITY; 589 heuristicGcdCancellation((number)result, cf); 778 779 const poly da = DEN(fa); 780 const poly db = DEN(fb); 781 782 783 if (db == NULL) 784 { 785 // b = ? // NULL 786 787 if(da == NULL) 788 { // both fa && fb are ?? // NULL! 789 assume (da == NULL && db == NULL); 790 DEN(result) = NULL; 791 COM(result) = 0; 792 } 793 else 794 { 795 assume (da != NULL && db == NULL); 796 DEN(result) = p_Copy(da, ntRing); 797 COM(result) = COM(fa) + MULT_COMPLEXITY; 798 heuristicGcdCancellation((number)result, cf); 799 } 800 } else 801 { // b = ?? / ?? 802 if (da == NULL) 803 { // a == ? // NULL 804 assume( db != NULL && da == NULL); 805 DEN(result) = p_Copy(db, ntRing); 806 COM(result) = COM(fb) + MULT_COMPLEXITY; 807 heuristicGcdCancellation((number)result, cf); 808 } 809 else /* both den's are != 1 */ 810 { 811 assume (da != NULL && db != NULL); 812 DEN(result) = pp_Mult_qq(da, db, ntRing); 813 COM(result) = COM(fa) + COM(fb) + MULT_COMPLEXITY; 814 heuristicGcdCancellation((number)result, cf); 815 } 816 } 817 818 // ntTest((number)result); 819 590 820 return (number)result; 591 821 } … … 593 823 number ntDiv(number a, number b, const coeffs cf) 594 824 { 595 ntTest(a); ntTest(b); 825 ntTest(a); 826 ntTest(b); 596 827 if (IS0(a)) return NULL; 597 828 if (IS0(b)) WerrorS(nDivBy0); … … 614 845 COM(result) = COM(fa) + COM(fb) + MULT_COMPLEXITY; 615 846 heuristicGcdCancellation((number)result, cf); 847 // ntTest((number)result); 616 848 return (number)result; 617 849 } … … 687 919 } 688 920 *b = pow; 921 ntTest(*b); 689 922 } 690 923 … … 813 1046 p_Delete(&DEN(f), ntRing); DEN(f) = NULL; 814 1047 } 1048 1049 if( DEN(f) != NULL ) 1050 if( !n_GreaterZero(pGetCoeff(DEN(f)), ntCoeffs) ) 1051 { 1052 NUM(f) = p_Neg(NUM(f), ntRing); 1053 DEN(f) = p_Neg(DEN(f), ntRing); 1054 } 1055 1056 ntTest((number)f); // TODO! 815 1057 } 816 1058 … … 818 1060 void heuristicGcdCancellation(number a, const coeffs cf) 819 1061 { 820 ntTest(a); 1062 // ntTest(a); // !!!!???? 821 1063 if (IS0(a)) return; 822 1064 823 1065 fraction f = (fraction)a; 824 if (DENIS1(f) || NUMIS1(f)) { COM(f) = 0; return; } 1066 if (DENIS1(f) || NUMIS1(f)) { COM(f) = 0; ntTest(a); return; } 1067 1068 assume( DEN(f) != NULL ); 825 1069 826 1070 /* check whether NUM(f) = DEN(f), and - if so - replace 'a' by 1 */ … … 830 1074 p_Delete(&DEN(f), ntRing); DEN(f) = NULL; 831 1075 COM(f) = 0; 832 return; 833 } 834 835 if (COM(f) <= BOUND_COMPLEXITY) return; 836 else definiteGcdCancellation(a, cf, TRUE); 837 } 838 839 /* modifies a */ 1076 } else 1077 { 1078 if (COM(f) > BOUND_COMPLEXITY) 1079 definiteGcdCancellation(a, cf, TRUE); 1080 1081 // TODO: check if it is enough to put the following into definiteGcdCancellation?! 1082 if( DEN(f) != NULL ) 1083 if( !n_GreaterZero(pGetCoeff(DEN(f)), ntCoeffs) ) 1084 { 1085 NUM(f) = p_Neg(NUM(f), ntRing); 1086 DEN(f) = p_Neg(DEN(f), ntRing); 1087 } 1088 } 1089 1090 1091 ntTest(a); // !!!!???? 1092 } 1093 1094 /// modifies a 840 1095 void definiteGcdCancellation(number a, const coeffs cf, 841 1096 BOOLEAN simpleTestsHaveAlreadyBeenPerformed) 842 1097 { 843 ntTest(a); 1098 ntTest(a); // !!!! 844 1099 845 1100 fraction f = (fraction)a; … … 856 1111 p_Delete(&DEN(f), ntRing); DEN(f) = NULL; 857 1112 COM(f) = 0; 1113 ntTest(a); // !!!! 858 1114 return; 859 1115 } … … 861 1117 862 1118 #ifdef HAVE_FACTORY 863 /* singclap_gcd destroys its arguments; we hence need copies: */864 poly pNum = p_Copy(NUM(f), ntRing);865 poly pDen = p_Copy(DEN(f), ntRing);866 867 1119 /* Note that, over Q, singclap_gcd will remove the denominators in all 868 1120 rational coefficients of pNum and pDen, before starting to compute 869 1121 the gcd. Thus, we do not need to ensure that the coefficients of 870 1122 pNum and pDen live in Z; they may well be elements of Q\Z. */ 871 poly pGcd = singclap_gcd(pNum, pDen, cf->extRing); 1123 /* singclap_gcd destroys its arguments; we hence need copies: */ 1124 poly pGcd = singclap_gcd(p_Copy(NUM(f), ntRing), p_Copy(DEN(f), ntRing), cf->extRing); 872 1125 if (p_IsConstant(pGcd, ntRing) && 873 1126 n_IsOne(p_GetCoeff(pGcd, ntRing), ntCoeffs)) … … 905 1158 COM(f) = 0; 906 1159 p_Delete(&pGcd, ntRing); 1160 1161 if( DEN(f) != NULL ) 1162 if( !n_GreaterZero(pGetCoeff(DEN(f)), ntCoeffs) ) 1163 { 1164 NUM(f) = p_Neg(NUM(f), ntRing); 1165 DEN(f) = p_Neg(DEN(f), ntRing); 1166 } 907 1167 #endif /* HAVE_FACTORY */ 1168 1169 ntTest(a); // !!!! 908 1170 } 909 1171 … … 932 1194 } 933 1195 } 1196 ntTest(a); // !!!! 934 1197 } 935 1198 … … 958 1221 } 959 1222 } 1223 ntTest(a); 960 1224 } 961 1225 … … 964 1228 poly p; 965 1229 const char * result = p_Read(s, p, ntRing); 966 if (p == NULL) { *a = NULL; return result; } 967 else 968 { 969 fraction f = (fraction)omAlloc0Bin(fractionObjectBin); 970 NUM(f) = p; 971 DEN(f) = NULL; 972 COM(f) = 0; 973 *a = (number)f; 974 return result; 975 } 1230 if (p == NULL) *a = NULL; 1231 else *a = ntInit(p, cf); 1232 return result; 976 1233 } 977 1234 … … 979 1236 { 980 1237 definiteGcdCancellation(a, cf, FALSE); 1238 ntTest(a); // !!!! 981 1239 } 982 1240 … … 1006 1264 number ntLcm(number a, number b, const coeffs cf) 1007 1265 { 1008 ntTest(a); ntTest(b); 1266 ntTest(a); 1267 ntTest(b); 1009 1268 fraction fb = (fraction)b; 1010 1269 if ((b==NULL)||(DEN(fb)==NULL)) return ntCopy(a,cf); … … 1026 1285 fraction result = (fraction)omAlloc0Bin(fractionObjectBin); 1027 1286 NUM(result) = pp_Mult_qq(NUM(fa),DEN(fb),ntRing); 1287 1288 ntTest((number)result); // !!!! 1289 1028 1290 return (number)result; 1029 1291 } 1030 else 1031 { /* return pa*pb/gcd */ 1292 1293 1294 /* return pa*pb/gcd */ 1032 1295 poly newNum = singclap_pdivide(NUM(fa), pGcd, ntRing); 1033 1296 p_Delete(&pGcd,ntRing); 1034 1297 fraction result = (fraction)omAlloc0Bin(fractionObjectBin); 1035 1298 NUM(result) = p_Mult_q(p_Copy(DEN(fb),ntRing),newNum,ntRing); 1299 ntTest((number)result); // !!!! 1036 1300 return (number)result; 1037 }1301 1038 1302 #else 1039 1303 Print("// factory needed: transext.cc:ntLcm\n"); … … 1045 1309 number ntGcd(number a, number b, const coeffs cf) 1046 1310 { 1047 ntTest(a); ntTest(b); 1311 ntTest(a); 1312 ntTest(b); 1048 1313 if (a==NULL) return ntCopy(b,cf); 1049 1314 if (b==NULL) return ntCopy(a,cf); … … 1062 1327 fraction result = (fraction)omAlloc0Bin(fractionObjectBin); 1063 1328 NUM(result) = pGcd; 1329 ntTest((number)result); // !!!! 1064 1330 return (number)result; 1065 1331 #else … … 1104 1370 } 1105 1371 } 1372 ntTest(a); // !!!! 1106 1373 return numDegree + denDegree + noOfTerms; 1107 1374 } … … 1110 1377 { 1111 1378 ntTest(a); 1112 if (IS0(a)) WerrorS(nDivBy0); 1379 if (IS0(a)) 1380 { 1381 WerrorS(nDivBy0); 1382 return NULL; 1383 } 1113 1384 fraction f = (fraction)a; 1385 assume( f != NULL ); 1386 1114 1387 fraction result = (fraction)omAlloc0Bin(fractionObjectBin); 1115 poly g; 1116 if (DENIS1(f)) g = p_One(ntRing); 1117 else g = p_Copy(DEN(f), ntRing); 1118 NUM(result) = g; 1119 DEN(result) = p_Copy(NUM(f), ntRing); 1120 COM(result) = COM(f); 1388 1389 assume( NUM(f) != NULL ); 1390 const poly den = DEN(f); 1391 1392 if (den == NULL) 1393 NUM(result) = p_One(ntRing); 1394 else 1395 NUM(result) = p_Copy(den, ntRing); 1396 1397 if( !NUMIS1(f) ) 1398 { 1399 DEN(result) = p_Copy(NUM(f), ntRing); 1400 COM(result) = COM(f); 1401 } 1402 else 1403 { 1404 DEN(result) = NULL; 1405 COM(result) = 0; 1406 } 1407 ntTest((number)result); // !!!! 1121 1408 return (number)result; 1122 1409 } … … 1126 1413 { 1127 1414 if (n_IsZero(a, src)) return NULL; 1415 assume(n_Test(a, src)); 1128 1416 assume(src == dst->extRing->cf); 1129 poly p = p_Init(dst->extRing); 1130 number na=n_Copy(a, src); 1131 n_Normalize(na, src); 1132 p_SetCoeff0(p, na, dst->extRing); 1417 return ntInit(p_NSet(n_Copy(a, src), dst->extRing), dst); 1418 } 1419 1420 /* assumes that src = Z/p, dst = Q(t_1, ..., t_s) */ 1421 number ntMapP0(number a, const coeffs src, const coeffs dst) 1422 { 1423 if (n_IsZero(a, src)) return NULL; 1424 assume(n_Test(a, src)); 1425 /* mapping via intermediate int: */ 1426 int n = n_Int(a, src); 1427 number q = n_Init(n, dst->extRing->cf); 1428 if (n_IsZero(q, dst->extRing->cf)) 1429 { 1430 n_Delete(&q, dst->extRing->cf); 1431 return NULL; 1432 } 1433 return ntInit(p_NSet(q, dst->extRing), dst); 1434 } 1435 1436 /* assumes that either src = Q(t_1, ..., t_s), dst = Q(t_1, ..., t_s), or 1437 src = Z/p(t_1, ..., t_s), dst = Z/p(t_1, ..., t_s) */ 1438 number ntCopyMap(number a, const coeffs cf, const coeffs dst) 1439 { 1440 // if (n_IsZero(a, cf)) return NULL; 1441 1442 ntTest(a); 1443 1444 if (IS0(a)) return NULL; 1445 1446 const ring rSrc = cf->extRing; 1447 const ring rDst = dst->extRing; 1448 1449 if( rSrc == rDst ) 1450 return ntCopy(a, dst); // USUALLY WRONG! 1451 1452 fraction f = (fraction)a; 1453 poly g = prCopyR(NUM(f), rSrc, rDst); 1454 1455 poly h = NULL; 1456 1457 if (!DENIS1(f)) 1458 h = prCopyR(DEN(f), rSrc, rDst); 1459 1460 fraction result = (fraction)omAlloc0Bin(fractionObjectBin); 1461 1462 NUM(result) = g; 1463 DEN(result) = h; 1464 COM(result) = COM(f); 1465 assume(n_Test((number)result, dst)); 1466 return (number)result; 1467 } 1468 1469 number ntCopyAlg(number a, const coeffs cf, const coeffs dst) 1470 { 1471 assume( n_Test(a, cf) ); 1472 if (n_IsZero(a, cf)) return NULL; 1473 1474 fraction f = (fraction)omAlloc0Bin(fractionObjectBin); 1475 // DEN(f) = NULL; COM(f) = 0; 1476 NUM(f) = prCopyR((poly)a, cf->extRing, dst->extRing); 1477 assume(n_Test((number)f, dst)); 1478 return (number)f; 1479 } 1480 1481 /* assumes that src = Q, dst = Z/p(t_1, ..., t_s) */ 1482 number ntMap0P(number a, const coeffs src, const coeffs dst) 1483 { 1484 assume( n_Test(a, src) ); 1485 if (n_IsZero(a, src)) return NULL; 1486 int p = rChar(dst->extRing); 1487 number q = nlModP(a, src, dst->extRing->cf); 1488 1489 if (n_IsZero(q, dst->extRing->cf)) 1490 { 1491 n_Delete(&q, dst->extRing->cf); 1492 return NULL; 1493 } 1494 1495 poly g = p_NSet(q, dst->extRing); 1496 1497 fraction f = (fraction)omAlloc0Bin(fractionObjectBin); 1498 NUM(f) = g; // DEN(f) = NULL; COM(f) = 0; 1499 assume(n_Test((number)f, dst)); 1500 return (number)f; 1501 } 1502 1503 /* assumes that src = Z/p, dst = Z/p(t_1, ..., t_s) */ 1504 number ntMapPP(number a, const coeffs src, const coeffs dst) 1505 { 1506 assume( n_Test(a, src) ); 1507 if (n_IsZero(a, src)) return NULL; 1508 assume(src == dst->extRing->cf); 1509 poly p = p_One(dst->extRing); 1510 p_SetCoeff(p, n_Copy(a, src), dst->extRing); 1133 1511 fraction f = (fraction)omAlloc0Bin(fractionObjectBin); 1134 1512 NUM(f) = p; DEN(f) = NULL; COM(f) = 0; 1513 assume(n_Test((number)f, dst)); 1135 1514 return (number)f; 1136 1515 } 1137 1516 1138 /* assumes that src = Z/p, dst = Q(t_1, ..., t_s) */ 1139 number ntMapP0(number a, const coeffs src, const coeffs dst) 1140 { 1517 /* assumes that src = Z/u, dst = Z/p(t_1, ..., t_s), where u != p */ 1518 number ntMapUP(number a, const coeffs src, const coeffs dst) 1519 { 1520 assume( n_Test(a, src) ); 1141 1521 if (n_IsZero(a, src)) return NULL; 1142 1522 /* mapping via intermediate int: */ … … 1153 1533 fraction f = (fraction)omAlloc0Bin(fractionObjectBin); 1154 1534 NUM(f) = p; DEN(f) = NULL; COM(f) = 0; 1155 return (number)f; 1156 } 1157 1158 /* assumes that either src = Q(t_1, ..., t_s), dst = Q(t_1, ..., t_s), or 1159 src = Z/p(t_1, ..., t_s), dst = Z/p(t_1, ..., t_s) */ 1160 number ntCopyMap(number a, const coeffs cf, const coeffs dst) 1161 { 1162 // if (n_IsZero(a, cf)) return NULL; 1163 1164 ntTest(a); 1165 1166 if (IS0(a)) return NULL; 1167 1168 const ring rSrc = cf->extRing; 1169 const ring rDst = dst->extRing; 1170 1171 if( rSrc == rDst ) 1172 return ntCopy(a, dst); // USUALLY WRONG! 1173 1174 fraction f = (fraction)a; 1175 poly g = prCopyR(NUM(f), rSrc, rDst); 1176 1177 poly h = NULL; 1178 1179 if (!DENIS1(f)) 1180 h = prCopyR(DEN(f), rSrc, rDst); 1181 1182 fraction result = (fraction)omAlloc0Bin(fractionObjectBin); 1183 1184 NUM(result) = g; 1185 DEN(result) = h; 1186 COM(result) = COM(f); 1187 return (number)result; 1188 } 1189 1190 number ntCopyAlg(number a, const coeffs cf, const coeffs dst) 1191 { 1192 if (n_IsZero(a, cf)) return NULL; 1193 1194 fraction f = (fraction)omAlloc0Bin(fractionObjectBin); 1195 // DEN(f) = NULL; COM(f) = 0; 1196 NUM(f) = prCopyR((poly)a, cf->extRing, dst->extRing); 1197 return (number)f; 1198 } 1199 1200 /* assumes that src = Q, dst = Z/p(t_1, ..., t_s) */ 1201 number ntMap0P(number a, const coeffs src, const coeffs dst) 1202 { 1203 if (n_IsZero(a, src)) return NULL; 1204 int p = rChar(dst->extRing); 1205 number q = nlModP(a, src, dst->extRing->cf); 1206 1207 if (n_IsZero(q, dst->extRing->cf)) 1208 { 1209 n_Delete(&q, dst->extRing->cf); 1210 return NULL; 1211 } 1212 1213 poly g = p_NSet(q, dst->extRing); 1214 1215 fraction f = (fraction)omAlloc0Bin(fractionObjectBin); 1216 NUM(f) = g; // DEN(f) = NULL; COM(f) = 0; 1217 return (number)f; 1218 } 1219 1220 /* assumes that src = Z/p, dst = Z/p(t_1, ..., t_s) */ 1221 number ntMapPP(number a, const coeffs src, const coeffs dst) 1222 { 1223 if (n_IsZero(a, src)) return NULL; 1224 assume(src == dst->extRing->cf); 1225 poly p = p_One(dst->extRing); 1226 p_SetCoeff(p, n_Copy(a, src), dst->extRing); 1227 fraction f = (fraction)omAlloc0Bin(fractionObjectBin); 1228 NUM(f) = p; DEN(f) = NULL; COM(f) = 0; 1229 return (number)f; 1230 } 1231 1232 /* assumes that src = Z/u, dst = Z/p(t_1, ..., t_s), where u != p */ 1233 number ntMapUP(number a, const coeffs src, const coeffs dst) 1234 { 1235 if (n_IsZero(a, src)) return NULL; 1236 /* mapping via intermediate int: */ 1237 int n = n_Int(a, src); 1238 number q = n_Init(n, dst->extRing->cf); 1239 poly p; 1240 if (n_IsZero(q, dst->extRing->cf)) 1241 { 1242 n_Delete(&q, dst->extRing->cf); 1243 return NULL; 1244 } 1245 p = p_One(dst->extRing); 1246 p_SetCoeff(p, q, dst->extRing); 1247 fraction f = (fraction)omAlloc0Bin(fractionObjectBin); 1248 NUM(f) = p; DEN(f) = NULL; COM(f) = 0; 1535 assume(n_Test((number)f, dst)); 1249 1536 return (number)f; 1250 1537 } … … 1349 1636 //DEN(result) = NULL; // done by omAlloc0Bin 1350 1637 //COM(result) = 0; // done by omAlloc0Bin 1638 ntTest((number)result); 1351 1639 return (number)result; 1352 1640 } … … 1363 1651 static int ntParDeg(number a, const coeffs cf) 1364 1652 { 1653 ntTest(a); 1365 1654 if (IS0(a)) return -1; 1366 1655 fraction fa = (fraction)a; … … 1386 1675 COM(f) = 0; 1387 1676 1677 ntTest((number)f); 1678 1388 1679 return (number)f; 1389 1680 } … … 1392 1683 int ntIsParam(number m, const coeffs cf) 1393 1684 { 1685 ntTest(m); 1394 1686 assume(getCoeffType(cf) == ID); 1395 1687 … … 1405 1697 } 1406 1698 1407 static void ntClearContent(ICoeffsEnumerator& /*numberCollectionEnumerator*/, number& c, const coeffs cf) 1699 struct NTNumConverter 1700 { 1701 static inline poly convert(const number& n) 1702 { 1703 // suitable for trans. ext. numbers that are fractions of polys 1704 return NUM((fraction)n); // return the numerator 1705 } 1706 }; 1707 1708 1709 static void ntClearContent(ICoeffsEnumerator& numberCollectionEnumerator, number& c, const coeffs cf) 1408 1710 { 1409 1711 assume(cf != NULL); 1410 1712 assume(getCoeffType(cf) == ID); 1411 assume(nCoeff_is_Q_a(cf)); // only over Q(a), while the default impl. is used over Zp(a) ! 1412 // all coeffs are given by integers!!! 1413 1414 c = n_Init(1, cf); 1415 assume(FALSE); // TODO: NOT YET IMPLEMENTED!!! 1416 1417 // numberCollectionEnumerator.Reset(); 1418 // 1419 // c = numberCollectionEnumerator.Current(); 1420 // 1421 // n_Normalize(c, r); 1422 // 1423 // if (!n_IsOne(c, r)) 1424 // { 1425 // numberCollectionEnumerator.Current() = n_Init(1, r); // ??? 1426 // 1427 // number inv = n_Invers(c, r); 1428 // 1429 // while( numberCollectionEnumerator.MoveNext() ) 1430 // { 1431 // number &n = numberCollectionEnumerator.Current(); 1432 // n_Normalize(n, r); // ? 1433 // n_InpMult(n, inv, r); 1434 // } 1435 // 1436 // n_Delete(&inv, r); 1437 // } 1438 } 1439 1440 static void ntClearDenominators(ICoeffsEnumerator& /*numberCollectionEnumerator*/, number& c, const coeffs cf) 1713 // all coeffs are given by fractions of polynomails over integers!!! 1714 // without denominators!!! 1715 1716 const ring R = cf->extRing; 1717 assume(R != NULL); 1718 const coeffs Q = R->cf; 1719 assume(Q != NULL); 1720 assume(nCoeff_is_Q(Q)); 1721 1722 1723 numberCollectionEnumerator.Reset(); 1724 1725 if( !numberCollectionEnumerator.MoveNext() ) // empty zero polynomial? 1726 { 1727 c = ntInit(1, cf); 1728 return; 1729 } 1730 1731 // all coeffs are given by integers after returning from this routine 1732 1733 // part 1, collect product of all denominators /gcds 1734 poly cand = NULL; 1735 1736 do 1737 { 1738 number &n = numberCollectionEnumerator.Current(); 1739 1740 ntNormalize(n, cf); 1741 1742 fraction f = (fraction)n; 1743 1744 assume( f != NULL ); 1745 1746 const poly den = DEN(f); 1747 1748 assume( den == NULL ); // ?? / 1 ? 1749 1750 const poly num = NUM(f); 1751 1752 if( cand == NULL ) 1753 cand = p_Copy(num, R); 1754 else 1755 cand = singclap_gcd(cand, p_Copy(num, R), R); // gcd(cand, num) 1756 1757 if( p_IsConstant(cand, R) ) 1758 break; 1759 } 1760 while( numberCollectionEnumerator.MoveNext() ) ; 1761 1762 1763 // part2: all coeffs = all coeffs * cand 1764 if( cand != NULL ) 1765 { 1766 if( !p_IsConstant(cand, R) ) 1767 { 1768 c = ntInit(cand, cf); 1769 numberCollectionEnumerator.Reset(); 1770 while (numberCollectionEnumerator.MoveNext() ) 1771 { 1772 number &n = numberCollectionEnumerator.Current(); 1773 const number t = ntDiv(n, c, cf); // TODO: rewrite!? 1774 ntDelete(&n, cf); 1775 n = t; 1776 } 1777 } // else NUM (result) = p_One(R); 1778 else { p_Delete(&cand, R); cand = NULL; } 1779 } 1780 1781 // Quick and dirty fix for constant content clearing: consider numerators??? 1782 CRecursivePolyCoeffsEnumerator<NTNumConverter> itr(numberCollectionEnumerator); // recursively treat the NUM(numbers) as polys! 1783 number cc; 1784 1785 // nlClearContentNoPositiveLead(itr, cc, Q); // TODO: get rid of (-LC) normalization!? 1786 nlClearContent(itr, cc, Q); 1787 number g = ntInit(p_NSet(cc, R), cf); 1788 1789 if( cand != NULL ) 1790 { 1791 number gg = ntMult(g, c, cf); 1792 ntDelete(&g, cf); 1793 ntDelete(&c, cf); c = gg; 1794 } else 1795 c = g; 1796 ntTest(c); 1797 } 1798 1799 static void ntClearDenominators(ICoeffsEnumerator& numberCollectionEnumerator, number& c, const coeffs cf) 1441 1800 { 1442 1801 assume(cf != NULL); 1443 1802 assume(getCoeffType(cf) == ID); // both over Q(a) and Zp(a)! 1444 // all coeffs are given by integers!!! 1445 1446 c = n_Init(1, cf); 1447 assume(FALSE); // TODO: NOT YET IMPLEMENTED!!! 1803 // all coeffs are given by fractions of polynomails over integers!!! 1804 1805 numberCollectionEnumerator.Reset(); 1806 1807 if( !numberCollectionEnumerator.MoveNext() ) // empty zero polynomial? 1808 { 1809 c = ntInit(1, cf); 1810 return; 1811 } 1812 1813 // all coeffs are given by integers after returning from this routine 1814 1815 // part 1, collect product of all denominators /gcds 1816 poly cand = NULL; 1817 1818 const ring R = cf->extRing; 1819 assume(R != NULL); 1820 1821 const coeffs Q = R->cf; 1822 assume(Q != NULL); 1823 // assume(nCoeff_is_Q(Q)); 1824 1825 do 1826 { 1827 number &n = numberCollectionEnumerator.Current(); 1828 1829 ntNormalize(n, cf); 1830 1831 fraction f = (fraction)n; 1832 1833 assume( f != NULL ); 1834 1835 const poly den = DEN(f); 1836 1837 if( den == NULL ) // ?? / 1 ? 1838 continue; 1839 1840 if( cand == NULL ) 1841 cand = p_Copy(den, R); 1842 else 1843 { 1844 // cand === LCM( cand, den )!!!! 1845 // NOTE: maybe it's better to make the product and clearcontent afterwards!? 1846 // TODO: move the following to factory? 1847 poly gcd = singclap_gcd(p_Copy(cand, R), p_Copy(den, R), R); // gcd(cand, den) is monic no mater leading coeffs! :(((( 1848 // assume( n_IsOne(pGetCoeff(gcd), Q) ); // TODO: this may be wrong... 1849 cand = p_Mult_q(cand, p_Copy(den, R), R); // cand *= den 1850 const poly t = singclap_pdivide( cand, gcd, R ); // cand' * den / gcd(cand', den) 1851 p_Delete(&cand, R); 1852 p_Delete(&gcd, R); 1853 cand = t; 1854 } 1855 } 1856 while( numberCollectionEnumerator.MoveNext() ); 1857 1858 if( cand == NULL ) 1859 { 1860 c = ntInit(1, cf); 1861 return; 1862 } 1863 1864 c = ntInit(cand, cf); 1865 1866 numberCollectionEnumerator.Reset(); 1867 1868 number d = NULL; 1869 1870 while (numberCollectionEnumerator.MoveNext() ) 1871 { 1872 number &n = numberCollectionEnumerator.Current(); 1873 number t = ntMult(n, c, cf); // TODO: rewrite!? 1874 ntDelete(&n, cf); 1875 1876 ntNormalize(t, cf); // TODO: needed? 1877 n = t; 1878 1879 fraction f = (fraction)t; 1880 assume( f != NULL ); 1881 1882 const poly den = DEN(f); 1883 1884 if( den != NULL ) // ?? / ?? ? 1885 { 1886 assume( p_IsConstant(den, R) ); 1887 assume( pNext(den) == NULL ); 1888 1889 if( d == NULL ) 1890 d = n_Copy(pGetCoeff(den), Q); 1891 else 1892 { 1893 number g = n_Lcm(d, pGetCoeff(den), Q); 1894 n_Delete(&d, Q); d = g; 1895 } 1896 } 1897 } 1898 1899 if( d != NULL ) 1900 { 1901 numberCollectionEnumerator.Reset(); 1902 while (numberCollectionEnumerator.MoveNext() ) 1903 { 1904 number &n = numberCollectionEnumerator.Current(); 1905 fraction f = (fraction)n; 1906 1907 assume( f != NULL ); 1908 1909 const poly den = DEN(f); 1910 1911 if( den == NULL ) // ?? / 1 ? 1912 NUM(f) = p_Mult_nn(NUM(f), d, R); 1913 else 1914 { 1915 assume( p_IsConstant(den, R) ); 1916 assume( pNext(den) == NULL ); 1917 1918 number ddd = n_Div(d, pGetCoeff(den), Q); // but be an integer now!!! 1919 NUM(f) = p_Mult_nn(NUM(f), ddd, R); 1920 n_Delete(&ddd, Q); 1921 1922 p_Delete(&DEN(f), R); 1923 DEN(f) = NULL; // TODO: check if this is needed!? 1924 } 1925 1926 assume( DEN(f) == NULL ); 1927 } 1928 1929 NUM(c) = p_Mult_nn(NUM(c), d, R); 1930 n_Delete(&d, Q); 1931 } 1932 1933 1934 ntTest(c); 1448 1935 } 1449 1936 -
libpolys/polys/monomials/p_polys.cc
r9f6cc0 rdc79bd 2023 2023 void p_Content(poly ph, const ring r) 2024 2024 { 2025 assume( ph != NULL ); 2026 2027 assume( r != NULL ); assume( r->cf != NULL ); const coeffs C = r->cf; 2028 2029 2025 2030 #if CLEARENUMERATORS 2026 if( (ph != NULL) && nCoeff_is_Q(r->cf) ) 2027 { 2031 if( 0 ) 2032 { 2033 // experimentall (recursive enumerator treatment) of alg. Ext! 2028 2034 CPolyCoeffsEnumerator itr(ph); 2029 2035 n_ClearContent(itr, r->cf); 2030 2036 2031 assume( n_GreaterZero(pGetCoeff(ph),r->cf) ); 2032 2037 p_Test(ph, r); n_Test(pGetCoeff(ph), C); 2038 assume(n_GreaterZero(pGetCoeff(ph), C)); // ?? 2039 2040 // if(!n_GreaterZero(pGetCoeff(ph),r->cf)) ph = p_Neg(ph,r); 2033 2041 return; 2034 2042 } 2035 2043 #endif 2036 2044 2045 2037 2046 #ifdef HAVE_RINGS 2038 2047 if (rField_is_Ring(r)) 2039 2048 { 2040 if ( (ph!=NULL) &&rField_has_Units(r))2049 if (rField_has_Units(r)) 2041 2050 { 2042 2051 number k = n_GetUnit(pGetCoeff(ph),r->cf); … … 2053 2062 pIter(h); 2054 2063 } 2055 assume( n_GreaterZero(pGetCoeff(ph),r->cf) ); 2064 // assume( n_GreaterZero(pGetCoeff(ph),r->cf) ); 2065 // if(!n_GreaterZero(pGetCoeff(ph),r->cf)) ph = p_Neg(ph,r); 2056 2066 } 2057 2067 n_Delete(&k,r->cf); … … 2070 2080 else 2071 2081 { 2082 assume( pNext(ph) != NULL ); 2072 2083 #if CLEARENUMERATORS 2073 if( (ph != NULL) && nCoeff_is_Q(r->cf) ) 2074 { 2084 if( nCoeff_is_Q(r->cf) || nCoeff_is_Q_a(r->cf) ) 2085 { 2086 // experimentall (recursive enumerator treatment) of alg. Ext! 2075 2087 CPolyCoeffsEnumerator itr(ph); 2076 2088 n_ClearContent(itr, r->cf); 2077 assume( n_GreaterZero(pGetCoeff(ph),r->cf) ); 2089 2090 p_Test(ph, r); n_Test(pGetCoeff(ph), C); 2091 assume(n_GreaterZero(pGetCoeff(ph), C)); // ?? 2092 2093 // if(!n_GreaterZero(pGetCoeff(ph),r->cf)) ph = p_Neg(ph,r); 2078 2094 return; 2079 2095 } … … 2082 2098 n_Normalize(pGetCoeff(ph),r->cf); 2083 2099 if(!n_GreaterZero(pGetCoeff(ph),r->cf)) ph = p_Neg(ph,r); 2084 if (rField_is_Q(r)) 2100 if (rField_is_Q(r)) // should not be used anymore if CLEARENUMERATORS is 1 2085 2101 { 2086 2102 h=p_InitContent(ph,r); … … 2132 2148 // } 2133 2149 #endif 2134 if (rField_is_Q_a(r)) 2150 if (rField_is_Q_a(r)) 2135 2151 { 2136 2152 // we only need special handling for alg. ext. … … 2452 2468 poly p_Cleardenom(poly ph, const ring r) 2453 2469 { 2454 const coeffs C = r->cf; 2470 if( ph == NULL ) 2471 return NULL; 2472 2473 assume( r != NULL ); assume( r->cf != NULL ); const coeffs C = r->cf; 2474 2475 #if CLEARENUMERATORS 2476 if( 0 ) 2477 { 2478 CPolyCoeffsEnumerator itr(ph); 2479 2480 n_ClearDenominators(itr, C); 2481 2482 n_ClearContent(itr, C); // divide out the content 2483 2484 p_Test(ph, r); n_Test(pGetCoeff(ph), C); 2485 assume(n_GreaterZero(pGetCoeff(ph), C)); // ?? 2486 // if(!n_GreaterZero(pGetCoeff(ph),C)) ph = p_Neg(ph,r); 2487 2488 return ph; 2489 } 2490 #endif 2455 2491 2456 2492 poly start=ph; 2457 2493 2458 #if CLEARENUMERATORS2459 if( (ph != NULL) && nCoeff_is_Q(C) )2460 {2461 CPolyCoeffsEnumerator itr(ph);2462 n_ClearDenominators(itr, C);2463 n_ClearContent(itr, C); // divide out the content2464 2465 assume( n_GreaterZero(pGetCoeff(ph),C) );2466 2467 return start;2468 }2469 #endif2470 2471 2494 number d, h; 2472 2495 poly p; … … 2477 2500 p_Content(ph,r); 2478 2501 assume( n_GreaterZero(pGetCoeff(ph),C) ); 2502 if(!n_GreaterZero(pGetCoeff(ph),C)) ph = p_Neg(ph,r); 2479 2503 return start; 2480 2504 } … … 2484 2508 { 2485 2509 assume( n_GreaterZero(pGetCoeff(ph),C) ); 2510 if(!n_GreaterZero(pGetCoeff(ph),C)) ph = p_Neg(ph,r); 2486 2511 return start; 2487 2512 } … … 2507 2532 2508 2533 assume( n_GreaterZero(pGetCoeff(ph),C) ); 2534 if(!n_GreaterZero(pGetCoeff(ph),C)) ph = p_Neg(ph,r); 2509 2535 2510 2536 return start; 2511 2537 } 2512 2538 2539 assume(pNext(p)!=NULL); 2540 2513 2541 #if CLEARENUMERATORS 2514 if( (ph != NULL) && nCoeff_is_Q(C) )2542 if( nCoeff_is_Q(C) || nCoeff_is_Q_a(C) ) 2515 2543 { 2516 2544 CPolyCoeffsEnumerator itr(ph); 2545 2517 2546 n_ClearDenominators(itr, C); 2547 2518 2548 n_ClearContent(itr, C); // divide out the content 2519 2549 2520 assume( n_GreaterZero(pGetCoeff(ph),C) ); 2550 p_Test(ph, r); n_Test(pGetCoeff(ph), C); 2551 assume(n_GreaterZero(pGetCoeff(ph), C)); // ?? 2552 // if(!n_GreaterZero(pGetCoeff(ph),C)) ph = p_Neg(ph,r); 2521 2553 2522 2554 return start; … … 2617 2649 2618 2650 assume( n_GreaterZero(pGetCoeff(ph),C) ); 2651 if(!n_GreaterZero(pGetCoeff(ph),C)) ph = p_Neg(ph,r); 2619 2652 2620 2653 return start; … … 2625 2658 const coeffs C = r->cf; 2626 2659 number d, h; 2627 poly p; 2628 2629 p = ph; 2630 2631 assume(ph != NULL); 2632 2633 2660 2661 assume( ph != NULL ); 2662 2663 poly p = ph; 2634 2664 2635 2665 #if CLEARENUMERATORS 2636 if( (ph != NULL) && nCoeff_is_Q(C))2666 if( 0 ) 2637 2667 { 2638 2668 CPolyCoeffsEnumerator itr(ph); 2669 2639 2670 n_ClearDenominators(itr, d, C); // multiply with common denom. d 2640 2671 n_ClearContent(itr, h, C); // divide by the content h … … 2645 2676 n_Delete(&h, C); 2646 2677 2678 n_Test(c, C); 2679 2680 p_Test(ph, r); n_Test(pGetCoeff(ph), C); 2681 assume(n_GreaterZero(pGetCoeff(ph), C)); // ?? 2682 /* 2683 if(!n_GreaterZero(pGetCoeff(ph),C)) 2684 { 2685 ph = p_Neg(ph,r); 2686 c = n_Neg(c, C); 2687 } 2688 */ 2689 return; 2690 } 2691 #endif 2692 2693 2694 if( pNext(p) == NULL ) 2695 { 2696 c=n_Invers(pGetCoeff(p), C); 2697 p_SetCoeff(p, n_Init(1, C), r); 2698 2647 2699 assume( n_GreaterZero(pGetCoeff(ph),C) ); 2700 if(!n_GreaterZero(pGetCoeff(ph),C)) 2701 { 2702 ph = p_Neg(ph,r); 2703 c = n_Neg(c, C); 2704 } 2648 2705 2649 2706 return; 2650 2707 } 2651 #endif 2708 2709 assume( pNext(p) != NULL ); 2652 2710 2653 if(pNext(p)==NULL) 2654 { 2655 c=n_Invers(pGetCoeff(p), C); 2656 p_SetCoeff(p, n_Init(1, C), r); 2657 2658 assume( n_GreaterZero(pGetCoeff(ph),C) ); 2711 #if CLEARENUMERATORS 2712 if( nCoeff_is_Q(C) || nCoeff_is_Q_a(C) ) 2713 { 2714 CPolyCoeffsEnumerator itr(ph); 2659 2715 2660 return;2661 }2662 2663 #if CLEARENUMERATORS2664 if( (ph != NULL) && nCoeff_is_Q(C) )2665 {2666 CPolyCoeffsEnumerator itr(ph);2667 2716 n_ClearDenominators(itr, d, C); // multiply with common denom. d 2668 2717 n_ClearContent(itr, h, C); // divide by the content h … … 2673 2722 n_Delete(&h, C); 2674 2723 2675 assume( n_GreaterZero(pGetCoeff(ph),C) ); 2676 2724 n_Test(c, C); 2725 2726 p_Test(ph, r); n_Test(pGetCoeff(ph), C); 2727 assume(n_GreaterZero(pGetCoeff(ph), C)); // ?? 2728 /* 2729 if(!n_GreaterZero(pGetCoeff(ph),C)) 2730 { 2731 ph = p_Neg(ph,r); 2732 c = n_Neg(c, C); 2733 } 2734 */ 2677 2735 return; 2678 2736 } … … 2766 2824 2767 2825 assume( n_GreaterZero(pGetCoeff(ph),C) ); 2826 if(!n_GreaterZero(pGetCoeff(ph),C)) 2827 { 2828 ph = p_Neg(ph,r); 2829 c = n_Neg(c, C); 2830 } 2831 2768 2832 } 2769 2833
Note: See TracChangeset
for help on using the changeset viewer.