My Project
Loading...
Searching...
No Matches
Functions
canonicalform.cc File Reference
#include "config.h"
#include "cf_assert.h"
#include "cf_factory.h"
#include "cf_defs.h"
#include "cf_globals.h"
#include "canonicalform.h"
#include "cf_iter.h"
#include "int_cf.h"
#include "cf_algorithm.h"
#include "imm.h"
#include "int_pp.h"
#include "gfops.h"
#include "facMul.h"
#include "facAlgFuncUtil.h"
#include "FLINTconvert.h"
#include "cf_binom.h"

Go to the source code of this file.

Functions

void divrem (const CanonicalForm &f, const CanonicalForm &g, CanonicalForm &q, CanonicalForm &r)
 
bool divremt (const CanonicalForm &f, const CanonicalForm &g, CanonicalForm &q, CanonicalForm &r)
 
bool tryDivremt (const CanonicalForm &f, const CanonicalForm &g, CanonicalForm &q, CanonicalForm &r, const CanonicalForm &M, bool &fail)
 same as divremt but handles zero divisors in case we are in Z_p[x]/(f) where f is not irreducible More...
 
bool operator== (const CanonicalForm &lhs, const CanonicalForm &rhs)
 operator ==() - compare canonical forms on (in)equality. More...
 
bool operator!= (const CanonicalForm &lhs, const CanonicalForm &rhs)
 operator !=() returns true iff lhs does not equal rhs. More...
 
bool operator> (const CanonicalForm &lhs, const CanonicalForm &rhs)
 operator >() - compare canonical forms. More...
 
bool operator< (const CanonicalForm &lhs, const CanonicalForm &rhs)
 
CanonicalForm bgcd (const CanonicalForm &f, const CanonicalForm &g)
 CanonicalForm bgcd ( const CanonicalForm & f, const CanonicalForm & g ) More...
 
CanonicalForm bextgcd (const CanonicalForm &f, const CanonicalForm &g, CanonicalForm &a, CanonicalForm &b)
 CanonicalForm bextgcd ( const CanonicalForm & f, const CanonicalForm & g, CanonicalForm & a, CanonicalForm & b ) More...
 
CanonicalForm blcm (const CanonicalForm &f, const CanonicalForm &g)
 
CanonicalForm power (const CanonicalForm &f, int n)
 exponentiation More...
 
CanonicalForm power (const Variable &v, int n)
 exponentiation More...
 
void On (int sw)
 switches More...
 
void Off (int sw)
 switches More...
 
bool isOn (int sw)
 switches More...
 

Function Documentation

◆ bextgcd()

CanonicalForm bextgcd ( const CanonicalForm & f, const CanonicalForm & g, CanonicalForm & a, CanonicalForm & b )

bextgcd() - return base coefficient extended gcd.

Definition at line 1722 of file canonicalform.cc.

1723{
1724 // check immediate cases
1725 int what = is_imm( g.value );
1726 if ( is_imm( f.value ) ) {
1727 ASSERT( ! what || (what == is_imm( f.value )), "incompatible operands" );
1728 if ( what == 0 )
1729 return g.value->bextgcdcoeff( f.value, b, a );
1730 else if ( what == INTMARK && ! cf_glob_switches.isOn( SW_RATIONAL ) ) {
1731 // calculate extended gcd using standard integer
1732 // arithmetic
1733 long fInt = imm2int( f.value );
1734 long gInt = imm2int( g.value );
1735
1736 // to avoid any system dpendencies with `%', we work
1737 // with positive numbers only. To a pity, we have to
1738 // redo all the checks when assigning to a and b.
1739 if ( fInt < 0 ) fInt = -fInt;
1740 if ( gInt < 0 ) gInt = -gInt;
1741 // swap fInt and gInt
1742 if ( gInt > fInt ) {
1743 long swap = gInt;
1744 gInt = fInt;
1745 fInt = swap;
1746 }
1747
1748 long u = 1; long v = 0;
1749 long uNext = 0; long vNext = 1;
1750
1751 // at any step, we have:
1752 // fInt_0 * u + gInt_0 * v = fInt
1753 // fInt_0 * uNext + gInt_0 * vNext = gInt
1754 // where fInt_0 and gInt_0 denote the values of fint
1755 // and gInt, resp., at the beginning
1756 while ( gInt ) {
1757 long r = fInt % gInt;
1758 long q = fInt / gInt;
1759 long uSwap = u - q * uNext;
1760 long vSwap = v - q * vNext;
1761
1762 // update variables
1763 fInt = gInt;
1764 gInt = r;
1765 u = uNext; v = vNext;
1766 uNext = uSwap; vNext = vSwap;
1767 }
1768
1769 // now, assign to a and b
1770 long fTest = imm2int( f.value );
1771 long gTest = imm2int( g.value );
1772 if ( gTest > fTest ) {
1773 a = v; b = u;
1774 } else {
1775 a = u; b = v;
1776 }
1777 if ( fTest < 0 ) a = -a;
1778 if ( gTest < 0 ) b = -b;
1779 return CanonicalForm( fInt );
1780 } else
1781 // stupid special cases
1782 if ( ! f.isZero() ) {
1783 a = 1/f; b = 0; return CanonicalForm( 1L );
1784 } else if ( ! g.isZero() ) {
1785 a = 0; b = 1/g; return CanonicalForm( 1L );
1786 } else {
1787 a = 0; b = 0; return CanonicalForm( 0L );
1788 }
1789 }
1790 else if ( what )
1791 return f.value->bextgcdcoeff( g.value, a, b );
1792
1793 int fLevel = f.value->level();
1794 int gLevel = g.value->level();
1795
1796 // check levels
1797 if ( fLevel == gLevel ) {
1798 fLevel = f.value->levelcoeff();
1799 gLevel = g.value->levelcoeff();
1800
1801 // check levelcoeffs
1802 if ( fLevel == gLevel )
1803 return f.value->bextgcdsame( g.value, a, b );
1804 else if ( fLevel < gLevel )
1805 return g.value->bextgcdcoeff( f.value, b, a );
1806 else
1807 return f.value->bextgcdcoeff( g.value, a, b );
1808 }
1809 else if ( fLevel < gLevel )
1810 return g.value->bextgcdcoeff( f.value, b, a );
1811 else
1812 return f.value->bextgcdcoeff( g.value, a, b );
1813}
#define swap(_i, _j)
int is_imm(const InternalCF *const ptr)
Definition: canonicalform.h:65
g
Definition: cfModGcd.cc:4090
CanonicalForm b
Definition: cfModGcd.cc:4103
#define ASSERT(expression, message)
Definition: cf_assert.h:99
static const int SW_RATIONAL
set to 1 for computations over Q
Definition: cf_defs.h:31
INST_VAR CFSwitches cf_glob_switches
Definition: cf_switches.cc:54
FILE * f
Definition: checklibs.c:9
bool isOn(int s) const
check if 's' is on
Definition: cf_switches.h:55
factory's main class
Definition: canonicalform.h:86
const Variable & v
< [in] a sqrfree bivariate poly
Definition: facBivar.h:39
static long gInt(number &a, const coeffs)
Definition: generics.cc:143
static long imm2int(const InternalCF *const imm)
Definition: imm.h:70
const long INTMARK
Definition: imm.h:37

◆ bgcd()

CanonicalForm bgcd ( const CanonicalForm & f, const CanonicalForm & g )

bgcd() - return base coefficient gcd.

If both f and g are integers and ‘SW_RATIONAL’ is off the positive greatest common divisor of f and g is returned. Otherwise, if ‘SW_RATIONAL’ is on or one of f and g is not an integer, the greatest common divisor is trivial: either zero if f and g equal zero or one (both from the current domain).

f and g should come from one base domain which should be not the prime power domain.

Implementation:

CanonicalForm::bgcd() handles the immediate case with a standard euclidean algorithm. For the non-immediate cases ‘InternalCF::bgcdsame()’ or ‘InternalCF::bgcdcoeff()’, resp. are called following the usual level/levelcoeff approach.

InternalCF::bgcdsame() and InternalCF::bgcdcoeff() throw an assertion ("not implemented")

InternalInteger::bgcdsame() is a wrapper around ‘mpz_gcd()’ which takes some care about immediate results and the sign of the result InternalInteger::bgcdcoeff() is a wrapper around ‘mpz_gcd_ui()’ which takes some care about the sign of the result

InternalRational::bgcdsame() and InternalRational::bgcdcoeff() always return one

Definition at line 1648 of file canonicalform.cc.

1649{
1650 // check immediate cases
1651 int what = is_imm( g.value );
1652 if ( is_imm( f.value ) )
1653 {
1654 ASSERT( ! what || (what == is_imm( f.value )), "incompatible operands" );
1655 if ( what == 0 )
1656 return g.value->bgcdcoeff( f.value );
1657 else if ( what == INTMARK && ! cf_glob_switches.isOn( SW_RATIONAL ) )
1658 {
1659 // calculate gcd using standard integer
1660 // arithmetic
1661 long fInt = imm2int( f.value );
1662 long gInt = imm2int( g.value );
1663
1664 if ( fInt < 0 ) fInt = -fInt;
1665 if ( gInt < 0 ) gInt = -gInt;
1666 // swap fInt and gInt
1667 if ( gInt > fInt )
1668 {
1669 long swap = gInt;
1670 gInt = fInt;
1671 fInt = swap;
1672 }
1673
1674 // now, 0 <= gInt <= fInt. Start the loop.
1675 while ( gInt )
1676 {
1677 // calculate (fInt, gInt) = (gInt, fInt%gInt)
1678 long r = fInt % gInt;
1679 fInt = gInt;
1680 gInt = r;
1681 }
1682
1683 return CanonicalForm( fInt );
1684 }
1685 else
1686 // we do not go for maximal speed for these stupid
1687 // special cases
1688 return CanonicalForm( f.isZero() && g.isZero() ? 0 : 1 );
1689 }
1690 else if ( what )
1691 return f.value->bgcdcoeff( g.value );
1692
1693 int fLevel = f.value->level();
1694 int gLevel = g.value->level();
1695
1696 // check levels
1697 if ( fLevel == gLevel )
1698 {
1699 fLevel = f.value->levelcoeff();
1700 gLevel = g.value->levelcoeff();
1701
1702 // check levelcoeffs
1703 if ( fLevel == gLevel )
1704 return f.value->bgcdsame( g.value );
1705 else if ( fLevel < gLevel )
1706 return g.value->bgcdcoeff( f.value );
1707 else
1708 return f.value->bgcdcoeff( g.value );
1709 }
1710 else if ( fLevel < gLevel )
1711 return g.value->bgcdcoeff( f.value );
1712 else
1713 return f.value->bgcdcoeff( g.value );
1714}

◆ blcm()

Definition at line 1816 of file canonicalform.cc.

1817{
1818 if ( f.isZero() || g.isZero() )
1819 return CanonicalForm( 0L );
1820/*
1821 else if (f.isOne())
1822 return g;
1823 else if (g.isOne())
1824 return f;
1825*/
1826 else
1827 return (f / bgcd( f, g )) * g;
1828}
CanonicalForm bgcd(const CanonicalForm &f, const CanonicalForm &g)
CanonicalForm bgcd ( const CanonicalForm & f, const CanonicalForm & g )

◆ divrem()

void divrem ( const CanonicalForm f,
const CanonicalForm g,
CanonicalForm q,
CanonicalForm r 
)

Definition at line 1032 of file canonicalform.cc.

1033{
1034 InternalCF * qq = 0, * rr = 0;
1035 int what = is_imm( f.value );
1036 if ( what )
1037 if ( is_imm( g.value ) ) {
1038 if ( what == FFMARK )
1039 imm_divrem_p( f.value, g.value, qq, rr );
1040 else if ( what == GFMARK )
1041 imm_divrem_gf( f.value, g.value, qq, rr );
1042 else
1043 imm_divrem( f.value, g.value, qq, rr );
1044 }
1045 else
1046 g.value->divremcoeff( f.value, qq, rr, true );
1047 else if ( (what=is_imm( g.value )) )
1048 f.value->divremcoeff( g.value, qq, rr, false );
1049 else if ( f.value->level() == g.value->level() )
1050 if ( f.value->levelcoeff() == g.value->levelcoeff() )
1051 f.value->divremsame( g.value, qq, rr );
1052 else if ( f.value->levelcoeff() > g.value->levelcoeff() )
1053 f.value->divremcoeff( g.value, qq, rr, false );
1054 else
1055 g.value->divremcoeff( f.value, qq, rr, true );
1056 else if ( f.value->level() > g.value->level() )
1057 f.value->divremcoeff( g.value, qq, rr, false );
1058 else
1059 g.value->divremcoeff( f.value, qq, rr, true );
1060 ASSERT( qq != 0 && rr != 0, "error in divrem" );
1061 q = CanonicalForm( qq );
1062 r = CanonicalForm( rr );
1063}
virtual class for internal CanonicalForm's
Definition: int_cf.h:47
void imm_divrem_gf(const InternalCF *const lhs, const InternalCF *const rhs, InternalCF *&q, InternalCF *&r)
Definition: imm.h:451
const long FFMARK
Definition: imm.h:38
void imm_divrem_p(const InternalCF *const lhs, const InternalCF *const rhs, InternalCF *&q, InternalCF *&r)
Definition: imm.h:445
const long GFMARK
Definition: imm.h:39
void imm_divrem(const InternalCF *const lhs, const InternalCF *const rhs, InternalCF *&q, InternalCF *&r)
Definition: imm.h:433

◆ divremt()

bool divremt ( const CanonicalForm f,
const CanonicalForm g,
CanonicalForm q,
CanonicalForm r 
)

Definition at line 1066 of file canonicalform.cc.

1067{
1068 InternalCF * qq = 0, * rr = 0;
1069 int what = is_imm( f.value );
1070 bool result = true;
1071 if ( what )
1072 if ( is_imm( g.value ) ) {
1073 if ( what == FFMARK )
1074 imm_divrem_p( f.value, g.value, qq, rr );
1075 else if ( what == GFMARK )
1076 imm_divrem_gf( f.value, g.value, qq, rr );
1077 else
1078 imm_divrem( f.value, g.value, qq, rr );
1079 }
1080 else
1081 result = g.value->divremcoefft( f.value, qq, rr, true );
1082 else if ( (what=is_imm( g.value )) )
1083 result = f.value->divremcoefft( g.value, qq, rr, false );
1084 else if ( f.value->level() == g.value->level() )
1085 if ( f.value->levelcoeff() == g.value->levelcoeff() )
1086 result = f.value->divremsamet( g.value, qq, rr );
1087 else if ( f.value->levelcoeff() > g.value->levelcoeff() )
1088 result = f.value->divremcoefft( g.value, qq, rr, false );
1089 else
1090 result = g.value->divremcoefft( f.value, qq, rr, true );
1091 else if ( f.value->level() > g.value->level() )
1092 result = f.value->divremcoefft( g.value, qq, rr, false );
1093 else
1094 result = g.value->divremcoefft( f.value, qq, rr, true );
1095 if ( result ) {
1096 ASSERT( qq != 0 && rr != 0, "error in divrem" );
1097 q = CanonicalForm( qq );
1098 r = CanonicalForm( rr );
1099 }
1100 else {
1101 q = 0; r = 0;
1102 }
1103 return result;
1104}
return result
Definition: facAbsBiFact.cc:75

◆ isOn()

bool isOn ( int  sw)

switches

Definition at line 1971 of file canonicalform.cc.

1972{
1973 return cf_glob_switches.isOn( sw );
1974}

◆ Off()

void Off ( int  sw)

switches

Definition at line 1964 of file canonicalform.cc.

1965{
1966 cf_glob_switches.Off( sw );
1967}
void Off(int s)
switch 's' off
Definition: cf_switches.h:53

◆ On()

void On ( int  sw)

switches

Definition at line 1957 of file canonicalform.cc.

1958{
1959 cf_glob_switches.On( sw );
1960}
void On(int s)
switch 's' on
Definition: cf_switches.h:51

◆ operator!=()

bool operator!= ( const CanonicalForm lhs,
const CanonicalForm rhs 
)

operator !=() returns true iff lhs does not equal rhs.

See also
CanonicalForm::operator ==()

Definition at line 1492 of file canonicalform.cc.

1493{
1494 if ( lhs.value == rhs.value )
1495 return false;
1496 else if ( is_imm( rhs.value ) || is_imm( lhs.value ) ) {
1497 ASSERT( ! is_imm( rhs.value ) ||
1498 ! is_imm( lhs.value ) ||
1499 is_imm( rhs.value ) == is_imm( lhs.value ),
1500 "incompatible operands" );
1501 return true;
1502 }
1503 else if ( lhs.value->level() != rhs.value->level() )
1504 return true;
1505 else if ( lhs.value->levelcoeff() != rhs.value->levelcoeff() )
1506 return true;
1507 else return rhs.value->comparesame( lhs.value ) != 0;
1508}
InternalCF * value
Definition: canonicalform.h:88
virtual int levelcoeff() const
Definition: int_cf.h:68
virtual int comparesame(InternalCF *) PVIRT_INT("comparesame")
virtual int level() const
Definition: int_cf.h:67

◆ operator<()

bool operator< ( const CanonicalForm lhs,
const CanonicalForm rhs 
)
See also
CanonicalForm::operator >()

Definition at line 1585 of file canonicalform.cc.

1587{
1588 int what = is_imm( rhs.value );
1589 if ( is_imm( lhs.value ) ) {
1590 ASSERT( ! what || (what == is_imm( lhs.value )), "incompatible operands" );
1591 if ( what == 0 )
1592 return rhs.value->comparecoeff( lhs.value ) > 0;
1593 else if ( what == INTMARK )
1594 return imm_cmp( lhs.value, rhs.value ) < 0;
1595 else if ( what == FFMARK )
1596 return imm_cmp_p( lhs.value, rhs.value ) < 0;
1597 else
1598 return imm_cmp_gf( lhs.value, rhs.value ) < 0;
1599 }
1600 else if ( what )
1601 return lhs.value->comparecoeff( rhs.value ) < 0;
1602 else if ( lhs.value->level() == rhs.value->level() )
1603 if ( lhs.value->levelcoeff() == rhs.value->levelcoeff() )
1604 return lhs.value->comparesame( rhs.value ) < 0;
1605 else if ( lhs.value->levelcoeff() > rhs.value->levelcoeff() )
1606 return lhs.value->comparecoeff( rhs.value ) < 0;
1607 else
1608 return rhs.value->comparecoeff( lhs.value ) > 0;
1609 else
1610 return lhs.value->level() < rhs.value->level();
1611}
virtual int comparecoeff(InternalCF *) PVIRT_INT("comparecoeff")
int imm_cmp_p(const InternalCF *const lhs, const InternalCF *const rhs)
Definition: imm.h:248
int imm_cmp_gf(const InternalCF *const lhs, const InternalCF *const rhs)
Definition: imm.h:259
int imm_cmp(const InternalCF *const lhs, const InternalCF *const rhs)
imm_cmp(), imm_cmp_p(), imm_cmp_gf() - compare immediate objects.
Definition: imm.h:237

◆ operator==()

bool operator== ( const CanonicalForm lhs,
const CanonicalForm rhs 
)

operator ==() - compare canonical forms on (in)equality.

operator ==() returns true iff lhs equals rhs.

This is the point in factory where we essentially use that CanonicalForms in fact are canonical. There must not be two different representations of the same mathematical object, otherwise, such (in)equality will not be recognized by these operators. In other word, we rely on the fact that structural different factory objects in any case represent different mathematical objects.

So we use the following procedure to test on equality (and analogously on inequality). First, we check whether lhs.value equals rhs.value. If so we are ready and return true. Second, if one of the operands is immediate, but the other one not, we return false. Third, if the operand's levels differ we return false. Fourth, if the operand's levelcoeffs differ we return false. At last, we call the corresponding internal method to compare both operands.

Both operands should have coefficients from the same base domain.

Note: To compare with the zero or the unit of the current domain, you better use the methods ‘CanonicalForm::isZero()’ or ‘CanonicalForm::isOne()’, resp., than something like ‘f == 0’, since the latter is quite a lot slower.

See also
CanonicalForm::operator !=(), InternalCF::comparesame(), InternalInteger::comparesame(), InternalRational::comparesame(), InternalPoly::comparesame()

Definition at line 1467 of file canonicalform.cc.

1468{
1469 if ( lhs.value == rhs.value )
1470 return true;
1471 else if ( is_imm( rhs.value ) || is_imm( lhs.value ) ) {
1472 ASSERT( ! is_imm( rhs.value ) ||
1473 ! is_imm( lhs.value ) ||
1474 is_imm( rhs.value ) == is_imm( lhs.value ),
1475 "incompatible operands" );
1476 return false;
1477 }
1478 else if ( lhs.value->level() != rhs.value->level() )
1479 return false;
1480 else if ( lhs.value->levelcoeff() != rhs.value->levelcoeff() )
1481 return false;
1482 else
1483 return rhs.value->comparesame( lhs.value ) == 0;
1484}

◆ operator>()

bool operator> ( const CanonicalForm lhs,
const CanonicalForm rhs 
)

operator >() - compare canonical forms.

on size or level.

The most common and most useful application of these operators is to compare two integers or rationals, of course. However, these operators are defined on all other base domains and on polynomials, too. From a mathematical point of view this may seem meaningless, since there is no ordering on finite fields or on polynomials respecting the algebraic structure. Nevertheless, from a programmer's point of view it may be sensible to order these objects, e.g. to sort them.

Therefore, the ordering defined by these operators in any case is a total ordering which fulfills the law of trichotomy.

It is clear how this is done in the case of the integers and the rationals. For finite fields, all you can say is that zero is the minimal element w.r.t. the ordering, the other elements are ordered in an arbitrary (but total!) way. For polynomials, you have an ordering derived from the lexicographical ordering of monomials. E.g. if lm(f) < lm(g) w.r.t. lexicographic ordering, then f < g. For more details, refer to the documentation of ‘InternalPoly::operator <()’.

Both operands should have coefficients from the same base domain.

The scheme how both operators are implemented is allmost the same as for the assignment operators (check for immediates, then check levels, then check levelcoeffs, then call the appropriate internal comparesame()/comparecoeff() method). For more information, confer to the overview for the arithmetic operators.

See also
CanonicalForm::operator <(), InternalCF::comparesame(), InternalInteger::comparesame(), InternalRational::comparesame(), InternalPoly::comparesame(), InternalCF::comparecoeff(), InternalInteger::comparecoeff(), InternalRational::comparecoeff(), InternalPoly::comparecoeff(), imm_cmp(), imm_cmp_p(), imm_cmp_gf()

Definition at line 1555 of file canonicalform.cc.

1556{
1557 int what = is_imm( rhs.value );
1558 if ( is_imm( lhs.value ) ) {
1559 ASSERT( ! what || (what == is_imm( lhs.value )), "incompatible operands" );
1560 if ( what == 0 )
1561 return rhs.value->comparecoeff( lhs.value ) < 0;
1562 else if ( what == INTMARK )
1563 return imm_cmp( lhs.value, rhs.value ) > 0;
1564 else if ( what == FFMARK )
1565 return imm_cmp_p( lhs.value, rhs.value ) > 0;
1566 else
1567 return imm_cmp_gf( lhs.value, rhs.value ) > 0;
1568 }
1569 else if ( what )
1570 return lhs.value->comparecoeff( rhs.value ) > 0;
1571 else if ( lhs.value->level() == rhs.value->level() )
1572 if ( lhs.value->levelcoeff() == rhs.value->levelcoeff() )
1573 return lhs.value->comparesame( rhs.value ) > 0;
1574 else if ( lhs.value->levelcoeff() > rhs.value->levelcoeff() )
1575 return lhs.value->comparecoeff( rhs.value ) > 0;
1576 else
1577 return rhs.value->comparecoeff( lhs.value ) < 0;
1578 else
1579 return lhs.value->level() > rhs.value->level();
1580}

◆ power() [1/2]

CanonicalForm power ( const CanonicalForm f,
int  n 
)

exponentiation

Definition at line 1896 of file canonicalform.cc.

1897{
1898 ASSERT( n >= 0, "illegal exponent" );
1899 if ( f.isZero() )
1900 return CanonicalForm(0L);
1901 else if ( f.isOne() )
1902 return f;
1903 else if ( f == -1 )
1904 {
1905 if ( n % 2 == 0 )
1906 return CanonicalForm(1L);
1907 else
1908 return CanonicalForm(-1L);
1909 }
1910 else if ( n == 0 )
1911 return CanonicalForm(1L);
1912
1913 //else if (f.inGF())
1914 //{
1915 //}
1916 else
1917 {
1919 h=f;
1920 while(n%2==0)
1921 {
1922 h*=h;
1923 n/=2;
1924 }
1925 g=h;
1926 while(1)
1927 {
1928 n/=2;
1929 if(n==0)
1930 return g;
1931 h*=h;
1932 if(n%2!=0) g*=h;
1933 }
1934 }
1935}
STATIC_VAR Poly * h
Definition: janet.cc:971

◆ power() [2/2]

CanonicalForm power ( const Variable v,
int  n 
)

exponentiation

Definition at line 1939 of file canonicalform.cc.

1940{
1941 //ASSERT( n >= 0, "illegal exponent" );
1942 if ( n == 0 )
1943 return 1;
1944 else if ( n == 1 )
1945 return v;
1946 else if (( v.level() < 0 ) && (hasMipo(v)))
1947 {
1948 CanonicalForm result( v, n-1 );
1949 return result * v;
1950 }
1951 else
1952 return CanonicalForm( v, n );
1953}
int level() const
Definition: variable.h:49
bool hasMipo(const Variable &alpha)
Definition: variable.cc:226

◆ tryDivremt()

bool tryDivremt ( const CanonicalForm f,
const CanonicalForm g,
CanonicalForm q,
CanonicalForm r,
const CanonicalForm M,
bool &  fail 
)

same as divremt but handles zero divisors in case we are in Z_p[x]/(f) where f is not irreducible

Definition at line 1108 of file canonicalform.cc.

1109{
1110 ASSERT (getCharacteristic() > 0, "expected positive characteristic");
1111 ASSERT (!getReduce (M.mvar()), "do not reduce modulo M");
1112 fail= false;
1113 InternalCF * qq = 0, * rr = 0;
1114 int what = is_imm( f.value );
1115 bool result = true;
1116 if ( what )
1117 if ( is_imm( g.value ) ) {
1118 if ( what == FFMARK )
1119 imm_divrem_p( f.value, g.value, qq, rr );
1120 else if ( what == GFMARK )
1121 imm_divrem_gf( f.value, g.value, qq, rr );
1122 }
1123 else
1124 result = g.value->tryDivremcoefft( f.value, qq, rr, true, M, fail );
1125 else if ( (what=is_imm( g.value )) )
1126 result = f.value->tryDivremcoefft( g.value, qq, rr, false, M, fail );
1127 else if ( f.value->level() == g.value->level() )
1128 if ( f.value->levelcoeff() == g.value->levelcoeff() )
1129 result = f.value->tryDivremsamet( g.value, qq, rr, M, fail );
1130 else if ( f.value->levelcoeff() > g.value->levelcoeff() )
1131 result = f.value->tryDivremcoefft( g.value, qq, rr, false, M, fail );
1132 else
1133 result = g.value->tryDivremcoefft( f.value, qq, rr, true, M, fail );
1134 else if ( f.value->level() > g.value->level() )
1135 result = f.value->tryDivremcoefft( g.value, qq, rr, false, M, fail );
1136 else
1137 result = g.value->tryDivremcoefft( f.value, qq, rr, true, M, fail );
1138 if (fail)
1139 {
1140 q= 0;
1141 r= 0;
1142 return false;
1143 }
1144 if ( result ) {
1145 ASSERT( qq != 0 && rr != 0, "error in divrem" );
1146 q = CanonicalForm( qq );
1147 r = CanonicalForm( rr );
1148 q= reduce (q, M);
1149 r= reduce (r, M);
1150 }
1151 else {
1152 q = 0; r = 0;
1153 }
1154 return result;
1155}
CanonicalForm reduce(const CanonicalForm &f, const CanonicalForm &M)
polynomials in M.mvar() are considered coefficients M univariate monic polynomial the coefficients of...
Definition: cf_ops.cc:660
int FACTORY_PUBLIC getCharacteristic()
Definition: cf_char.cc:70
#define M
Definition: sirandom.c:25
bool getReduce(const Variable &alpha)
Definition: variable.cc:232