| 2989 | } |
| 2990 | |
| 2991 | CanonicalForm mulMod2 (const CanonicalForm& A, const CanonicalForm& B, |
| 2992 | const CanonicalForm& M) |
| 2993 | { |
| 2994 | if (A.isZero() || B.isZero()) |
| 2995 | return 0; |
| 2996 | |
| 2997 | ASSERT (M.isUnivariate(), "M must be univariate"); |
| 2998 | |
| 2999 | CanonicalForm F= mod (A, M); |
| 3000 | CanonicalForm G= mod (B, M); |
| 3001 | if (F.inCoeffDomain()) |
| 3002 | return G*F; |
| 3003 | if (G.inCoeffDomain()) |
| 3004 | return F*G; |
| 3005 | |
| 3006 | Variable y= M.mvar(); |
| 3007 | int degF= degree (F, y); |
| 3008 | int degG= degree (G, y); |
| 3009 | |
| 3010 | if ((degF < 1 && degG < 1) && (F.isUnivariate() && G.isUnivariate()) && |
| 3011 | (F.level() == G.level())) |
| 3012 | { |
| 3013 | CanonicalForm result= mulNTL (F, G); |
| 3014 | return mod (result, M); |
| 3015 | } |
| 3016 | else if (degF <= 1 && degG <= 1) |
| 3017 | { |
| 3018 | CanonicalForm result= F*G; |
| 3019 | return mod (result, M); |
| 3020 | } |
| 3021 | |
| 3022 | int sizeF= size (F); |
| 3023 | int sizeG= size (G); |
| 3024 | |
| 3025 | int fallBackToNaive= 50; |
| 3026 | if (sizeF < fallBackToNaive || sizeG < fallBackToNaive) |
| 3027 | { |
| 3028 | if (sizeF < sizeG) |
| 3029 | return mod (G*F, M); |
| 3030 | else |
| 3031 | return mod (F*G, M); |
| 3032 | } |
| 3033 | |
| 3034 | #ifdef HAVE_FLINT |
| 3035 | if (getCharacteristic() == 0) |
| 3036 | return mulMod2FLINTQa (F, G, M); |
| 3037 | #endif |
| 3038 | |
| 3039 | if (getCharacteristic() > 0 && CFFactory::gettype() != GaloisFieldDomain && |
| 3040 | (((degF-degG) < 50 && degF > degG) || ((degG-degF) < 50 && degF <= degG))) |
| 3041 | return mulMod2NTLFq (F, G, M); |
| 3042 | |
| 3043 | int m= (int) ceil (degree (M)/2.0); |
| 3044 | if (degF >= m || degG >= m) |
| 3045 | { |
| 3046 | CanonicalForm MLo= power (y, m); |
| 3047 | CanonicalForm MHi= power (y, degree (M) - m); |
| 3048 | CanonicalForm F0= mod (F, MLo); |
no test coverage detected