2012-09-22

SCIP in C++11 ― 2.5.3節その2


代数操作その5:濃い多項式と薄い多項式・多項式の商と剰余:問題2.892.91

個別の項リスト操作と多項式操作を分離するのにちょっと手間取るが、
出来てしまえばあとは結構楽。
特に濃い多項式の項リストは、単に規則正しく並んだ数のリストだから、
mapとかfilterとか使い放題だな。
なお薄い多項式と濃い多項式の演算では、
薄い多項式を濃い多項式より上位の型として型変換を行う。

多項式の剰余が表現できるってことは、体の代数拡大が表現できるってことなわけで。
複素数を多項式のx2+1での剰余で表現したり、
問題2.6を拡張すればできそうな群の表現と組み合わせて、
Galois群の計算とかしたりしてみたくなる誘惑に駆られるw

なお問題2.92は確かに、ホントに難しそうなのでパス。

----
class SparseTermList{
public:
    SparseTermList(const TagType tagIn="sparse"):tagString(tagIn)
    {
        put(makeList("empty-termlist?",makeList(this->getTag())),
            makeLeaf(function<List(List)>
                     ([this](const List& x)
                      {return(makeLeaf(this->isEmptyTermList(x)));})));
        put(makeList("restTerms",makeList(this->getTag())),
            makeLeaf(function<List(List)>
                     ([this](const List& x)
                      {return(this->tag(this->restTerms(x)));})));
        put(makeList("=zero?",makeList(this->getTag())),
            makeLeaf(function<List(List)>
                     ([this](const List& x)
                      {return(this->isZero(x));})));
        put(makeList("add",makeList(this->getTag(),this->getTag())),
            makeLeaf(function<List(List,List)>
                     ([this](const List& x,const List& y)
                      {return(this->tag(this->addTerms(x,y)));})));
        put(makeList("sub",makeList(this->getTag(),this->getTag())),
            makeLeaf(function<List(List,List)>
                     ([this](const List& x,const List& y)
                      {return(this->tag(this->addTerms(x,this->negate(y))));})));
        put(makeList("mul",makeList(this->getTag(),this->getTag())),
            makeLeaf(function<List(List,List)>
                     ([this](const List& x,const List& y)
                      {return(this->tag(this->mulTerms(x,y)));})));
        put(makeList("div",makeList(this->getTag(),this->getTag())),
            makeLeaf(function<List(List,List)>
                     ([this](const List& x,const List& y)
                      {
                          const List divTermResult(this->divTerms(x,y));
                          return(makeList(this->tag(car(divTermResult)),
                                          this->tag(cadr(divTermResult))));
                      })));
        put(makeList("termListOrder",makeList(this->getTag())),
            makeLeaf(function<List(List)>
                     ([this](const List& x)
                      {return(this->termListOrder(x));})));
        put(makeList("firstCoefficient",makeList(this->getTag())),
            makeLeaf(function<List(List)>
                     ([this](const List& x)
                      {return(this->firstCoefficient(x));})));
        put(makeList("make",this->getTag()),
            makeLeaf(function<List(List)>
                     ([this](const List& L)
                      {return(this->tag(L));})));
     }
    virtual ~SparseTermList(void){}

    const List makeTerm(const List& termOrder,
                        const List& termCoefficient)const
    {return(makeList(termOrder,termCoefficient));}

    const List theEmptyTermList(void)const{return(makeList());}

    const List firstTerm(const List& termList)const
    {return(car(termList));}
   
    const List restTerms(const List& termList)const
    {return(cdr(termList));}
   
    const bool isEmptyTermList(const List& termList)const
    {return(isNull(termList));}

    const List order(const List& term)const{return(car(term));}

    const List coefficient(const List& term)const{return(cadr(term));}

    const List isZero(const List& termList)const
    {
        return(makeLeaf
               (this->isEmptyTermList(termList)
                ||(makeLeaf(0)==this->termListOrder(termList)
                   && Generic::isZero(this->firstCoefficient(termList)))));
    }

    const List addTerms(const List& L1,const List& L2)const
    {
        if(this->isEmptyTermList(L1)){return(L2);}
        else if(this->isEmptyTermList(L2)){return(L1);}

        if(this->termListOrder(L1)>this->termListOrder(L2)){
            return(this->adjoinTerm
                   (this->firstTerm(L1),this->addTerms(this->restTerms(L1),L2)));
        }else if(this->termListOrder(L1)<this->termListOrder(L2)){
            return(this->adjoinTerm
                   (this->firstTerm(L2),this->addTerms(L1,this->restTerms(L2))));
        }
        return(this->adjoinTerm
               (this->makeTerm
                (this->termListOrder(L1),
                 Generic::add(this->firstCoefficient(L1),
                              this->firstCoefficient(L2))),
                this->addTerms(this->restTerms(L1),
                               this->restTerms(L2))));
    }

    const List mulTerms(const List& L1, const List& L2)const
    {
        if(this->isEmptyTermList(L1))
            {return(this->theEmptyTermList());}
        return(this->addTerms
               (this->mulTermsByAllTerms(this->firstTerm(L1),L2),
                this->mulTerms(this->restTerms(L1),L2)));
    }

    const List mulTermsByAllTerms(const List& t1, const List& L)const
    {
        if(this->isEmptyTermList(L))
            {return(this->theEmptyTermList());}

        const List t2(this->firstTerm(L));
        return(this->adjoinTerm
               (this->makeTerm
                (this->order(t1)+this->order(t2),
                 Generic::mul(this->coefficient(t1),this->coefficient(t2))),
                this->mulTermsByAllTerms(t1,this->restTerms(L))));
    }

    const List divTerms(const List& L1, const List& L2)const
    {
        if(this->isEmptyTermList(L1))
            {return(makeList(this->theEmptyTermList(),
                             this->theEmptyTermList()));}

        const List t1(this->firstTerm(L1));
        const List t2(this->firstTerm(L2));
        if(this->order(t2)>this->order(t1)){
            return(makeList(this->theEmptyTermList(),L1));
        }
        const List newCoefficient
            (Generic::div(this->coefficient(t1),this->coefficient(t2)));
        const List newOrder(this->order(t1)-this->order(t2));
        const List restOfResult
            (this->divTerms
             (this->addTerms
              (this->mulTermsByAllTerms
               (this->makeTerm(newOrder,Generic::negate(newCoefficient)),
                this->restTerms(L2)),
               this->restTerms(L1)),
              L2));

        const List quotient
            (this->adjoinTerm(this->makeTerm(newOrder,newCoefficient),
                              car(restOfResult)));
        return(makeList(quotient,cadr(restOfResult)));
    }
   
    const List adjoinTerm(const List& term, const List& destL)const
    {
        if(Generic::isZero(this->coefficient(term)))
            {return(destL);}
        return(cons(term,destL));
    }

    const List negateTermList(void)const
    {
        return(makeList
               (this->makeTerm(makeLeaf(0),Generic::makeNumber(-1))));
    }

    const List negate(const List& L)const
    {
        return(this->mulTerms
               (L,this->negateTermList()));
    }
    const List termListOrder(const List& L)const
    {
        return(this->order(car(L)));
    }

    const List firstCoefficient(const List& L)const
    {
        return(this->coefficient(this->firstTerm(L)));
    }

    const TagType getTag(void)const{return(this->tagString);}
   
    virtual const List tag(const List& x)const
    {return(attachTag(this->getTag(),x));}
   
private:
    const TagType tagString;
};

class DenseTermList{
public:
    DenseTermList(const TagType tagIn="dense"):tagString(tagIn)
    {
        put(makeList("empty-termlist?",makeList(this->getTag())),
            makeLeaf(function<List(List)>
                     ([this](const List& x)
                      {return(makeLeaf(this->isEmptyTermList(x)));})));
        put(makeList("restTerms",makeList(this->getTag())),
            makeLeaf(function<List(List)>
                     ([this](const List& x)
                      {return(this->tag(this->restTerms(x)));})));
        put(makeList("=zero?",makeList(this->getTag())),
            makeLeaf(function<List(List)>
                     ([this](const List& x)
                      {return(this->isZero(x));})));
        put(makeList("add",makeList(this->getTag(),this->getTag())),
            makeLeaf(function<List(List,List)>
                     ([this](const List& x,const List& y)
                      {return(this->tag(this->addTerms(x,y)));})));
        put(makeList("sub",makeList(this->getTag(),this->getTag())),
            makeLeaf(function<List(List,List)>
                     ([this](const List& x,const List& y)
                      {return(this->tag(this->addTerms(x,this->negate(y))));})));
        put(makeList("mul",makeList(this->getTag(),this->getTag())),
            makeLeaf(function<List(List,List)>
                     ([this](const List& x,const List& y)
                      {return(this->tag(this->mulTerms(x,y)));})));
        put(makeList("div",makeList(this->getTag(),this->getTag())),
            makeLeaf(function<List(List,List)>
                     ([this](const List& x,const List& y)
                      {
                          const List divTermResult(this->divTerms(x,y));
                          return(makeList(this->tag(car(divTermResult)),
                                          this->tag(cadr(divTermResult))));
                      })));
        put(makeList("negate",makeList(this->getTag())),
            makeLeaf(function<List(List)>
                     ([this](const List& x)
                      {return(this->tag(this->negate(x)));})));
        put(makeList("termListOrder",makeList(this->getTag())),
            makeLeaf(function<List(List)>
                     ([this](const List& x)
                      {return(this->termListOrder(x));})));
        put(makeList("firstCoefficient",makeList(this->getTag())),
            makeLeaf(function<List(List)>
                     ([this](const List& x)
                      {return(this->firstCoefficient(x));})));
        put(makeList("make",this->getTag()),
            makeLeaf(function<List(List)>
                     ([this](const List& L)
                      {return(this->tag(L));})));
     }
    virtual ~DenseTermList(void){}

    const List theEmptyTermList(void)const{return(makeList());}

    const List firstTerm(const List& termList)const
    {return(car(termList));}
   
    const List restTerms(const List& termList)const
    {return(cdr(termList));}
   
    const bool isEmptyTermList(const List& termList)const
    {return(isNull(termList));}

    const List zeroTermList(void)const
    {return(makeList(Generic::makeNumber(0)));}

    const List coefficient(const List& term)const{return(term);}

    const List isZero(const List& termList)const
    {
        return(makeLeaf
               (this->isEmptyTermList(termList)
                ||(this->termListOrder(termList)==makeLeaf(0)
                   && Generic::isZero(this->firstCoefficient(termList)))));
    }

    const List addTerms(const List& L1,const List& L2)const
    {
        if(this->termListOrder(L1)>this->termListOrder(L2)){
            return(cons(this->firstTerm(L1),
                        this->addTerms(restTerms(L1),L2)));
        }else if(this->termListOrder(L1)<this->termListOrder(L2)){
            return(cons(this->firstTerm(L2),
                        this->addTerms(L1,restTerms(L2))));
        }

        function<List(List,List)> addTermProcedure
            =[](const List& term1,const List& term2){
            return(Generic::add(term1,term2));
        };
        return(mapping(addTermProcedure,L1,L2));
    }
   
    const List mulTerms(const List& L1, const List& L2)const
    {
        if(this->isEmptyTermList(L1))
            {return(this->theEmptyTermList());}
        return(this->addTerms
               (this->mulTermsByAllTerms
                (this->firstTerm(L1),this->termListOrder(L1),L2),
                this->mulTerms(this->restTerms(L1),L2)));
    }

    const List mulTermsByAllTerms
    (const List& t1, const List& termOrder, const List& L)const
    {

        const function<List(List)> fillZeroProcedure
            =[](const List& elem){return(Generic::makeNumber(0));};
        const List fillZeros
            (mapping(fillZeroProcedure,
                     enumerateInterval(0,value<int>(termOrder)-1)));

        const function<List(List)> mulTermProcedure
            =[t1](const List& term)
            {return(Generic::mul(t1,term));};
        return(append(mapping(mulTermProcedure,L),fillZeros));
    }

    const List divTerms(const List& L1, const List& L2)const
    {
        if(this->isEmptyTermList(L1))
            {return(makeList(this->zeroTermList(),
                             this->zeroTermList()));}

        if(this->termListOrder(L2)>this->termListOrder(L1)){
            return(makeList(this->zeroTermList(),L1));
        }

        const List t1(this->firstTerm(L1));
        const List t2(this->firstTerm(L2));
        const List newCoefficient
            (Generic::div(this->coefficient(t1),this->coefficient(t2)));
        const List newOrder(this->termListOrder(L1)-this->termListOrder(L2));
        const List restOfResult
            (this->divTerms
             (this->addTerms
              (this->mulTermsByAllTerms
               (Generic::negate(newCoefficient),newOrder,this->restTerms(L2)),
               this->restTerms(L1)),
              L2));

        const function<List(List)> fillZeroProcedure
            =[](const List& elem){return(Generic::makeNumber(0));};
        const List fillZeros
            (mapping(fillZeroProcedure,
                     enumerateInterval(0,value<int>(newOrder)-1)));

        const List quotient
            (this->addTerms(cons(newCoefficient,fillZeros),
                            car(restOfResult)));
        return(makeList(quotient,cadr(restOfResult)));
    }

    const List negateTermList(void)const
    {return(makeList(Generic::makeNumber(-1)));}

    const List negate(const List& L)const
    {
        return(this->mulTerms
               (L,this->negateTermList()));
    }
    const List termListOrder(const List& L)const
    {return(makeLeaf(length(L)-1));}

    const List firstCoefficient(const List& L)const
    {
        return(this->coefficient(this->firstTerm(L)));
    }

    const TagType getTag(void)const{return(this->tagString);}
   
    virtual const List tag(const List& x)const
    {return(attachTag(this->getTag(),x));}
   
private:
    const TagType tagString;
};
//---------abstraction barrier---------
class PolynomialArithmetic{
public:
    PolynomialArithmetic(const TagType tagIn="polynomial")
        :tagString(tagIn),
         _sparseTermList(new SparseTermList()),
         _denseTermList(new DenseTermList())
    {
        put(makeList("gcd",makeList(this->getTag(),this->getTag())),
            makeLeaf(function<List(List,List)>
                     ([this](const List& x,const List& y)
                      {return(this->tag(this->gcd(x,y)));})));
        put(makeList("add",makeList(this->getTag(),this->getTag())),
            makeLeaf(function<List(List,List)>
                     ([this](const List& x,const List& y)
                      {return(drop(this->tag(this->addPolynomial(x,y))));})));
        put(makeList("mul",makeList(this->getTag(),this->getTag())),
            makeLeaf(function<List(List,List)>
                     ([this](const List& x,const List& y)
                      {return(drop(this->tag(this->mulPolynomial(x,y))));})));
        put(makeList("div",makeList(this->getTag(),this->getTag())),
            makeLeaf(function<List(List,List)>
                     ([this](const List& x,const List& y)
                      {
                          const auto divResult(this->divPolynomial(x,y));
                          return(makeList(drop(this->tag(car(divResult))),
                                          drop(this->tag(cadr(divResult)))));})));
        put(makeList("constant?",makeList(this->getTag())),
            makeLeaf(function<List(List)>
                     ([this](const List& x)
                      {return(this->isConstant(x));})));
        put(makeList("=zero?",makeList(this->getTag())),
            makeLeaf(function<List(List)>
                     ([this](const List& x)
                      {return(this->isZero(x));})));
        put(makeList("negate",makeList(this->getTag())),
            makeLeaf(function<List(List)>
                     ([this](const List& x)
                      {return(this->tag(this->negate(x)));})));
        put(makeList("variable",makeList(this->getTag())),
            makeLeaf(function<List(List)>
                     ([this](const List& x)
                      {return(this->variable(x));})));
        put(makeList("leadingCoefficient",makeList(this->getTag())),
            makeLeaf(function<List(List)>
                     ([this](const List& x)
                      {return(this->leadingCoefficient(x));})));
        put(makeList("polynomialOrder",makeList(this->getTag())),
            makeLeaf(function<List(List)>
                     ([this](const List& x)
                      {return(this->polynomialOrder(x));})));
        put(makeList("expressionString",makeList(this->getTag())),
            makeLeaf(function<List(List)>
                     ([this](const List& x)
                      {return(this->expressionString(x));})));
        put(makeList("make",this->getTag()),
            makeLeaf(function<List(List,List)>
                     ([this](const List& var, const List& terms)
                      {return(this->tag
                              (this->makePolynomial(var,terms)));})));

    }
    virtual ~PolynomialArithmetic(void){
        delete this->_sparseTermList;
        delete this->_denseTermList;
    }
   
    const List makePolynomial(const List& variable, const List& termList)const
    {return(makeList(variable,termList));}
   
    const List variable(const List& polynomial)const
    {return(car(polynomial));}

    const List termList(const List& polynomial)const
    {return(cadr(polynomial));}
   
    //same-variable?
    const bool isSameVariable(const List& v1,const List& v2)const
    {return(isVariable(v1) && isVariable(v2) && isEq(v1,v2));}

    //variable?
    const bool isVariable(const List& x)const
    {return(isSymbol(x));}


    const List gcd(const List& a, const List& b)const{
        if(makeLeaf(0)==b){return(a);}
        return(gcd(b,a%b));
    }

    const List addPolynomial
    (const List& p1, const List& p2)const
    {
        if(this->isSameVariable
           (this->variable(p1),this->variable(p2))){
            return(this->makePolynomial
                   (this->variable(p1),
                    Generic::add(this->termList(p1),this->termList(p2))));
        }
        cerr<<"Polynomials not in same variable -- ADD-POLY "
            <<listString(p1)<<listString(p2)<<endl;
        exit(1);
        return(makeList());
    }

    const List mulPolynomial
    (const List& p1, const List& p2)const
    {
        if(this->isSameVariable
           (this->variable(p1),this->variable(p2))){
            return(this->makePolynomial
                   (this->variable(p1),
                    Generic::mul(termList(p1),termList(p2))));
        }
        cerr<<"Polynomials not in same variable -- MUL-POLY "
            <<listString(p1)<<listString(p2)<<endl;
        exit(1);
        return(makeList());
    }


    const List divPolynomial
    (const List& p1, const List& p2)const
    {
        if(this->isSameVariable
           (this->variable(p1),this->variable(p2))){
            const List divTermResult
                (Generic::div(this->termList(p1),this->termList(p2)));
            return(makeList
                   (this->makePolynomial
                    (this->variable(p1),car(divTermResult)),
                    this->makePolynomial
                    (this->variable(p1),cadr(divTermResult))));
        }
        cerr<<"Polynomials not in same variable -- DIV-POLY "
            <<listString(p1)<<listString(p2)<<endl;
        exit(1);
        return(makeList());
    }

    const List isZero(const List& x)const
    {
        return(makeLeaf(Generic::isZero(this->termList(x))));
    }

    const List isConstant(const List& x)const
    {
        return(makeLeaf(this->polynomialOrder(x)==makeLeaf(0)));
    }

    const List negate(const List& polynomial)const
    {
        return(this->makePolynomial
               (this->variable(polynomial),
                Generic::negate(this->termList(polynomial))));
    }

    const List leadingCoefficient(const List& p)const
    {
        return(Generic::firstCoefficient(this->termList(p)));
    }

    const List polynomialOrder(const List& p)const
    {
        return(Generic::termListOrder(this->termList(p)));
    }

    const List expressionString(const List& x)const
    {
        string returnString("");
        if(Generic::isEmptyTermList(this->termList(x)))
            {return(makeLeaf(returnString));}

        if(!Generic::isZero(this->leadingCoefficient(x))){
            const string coefString
                (Generic::expressionString(this->leadingCoefficient(x)));
            if(typeTag(this->leadingCoefficient(x))=="polynomial"
               ||typeTag(this->leadingCoefficient(x))=="complex"){
                if(this->polynomialOrder(x)!=makeLeaf(0)){
                    returnString+="+("+coefString+")";
                }else{
                    if(coefString.front()=='-'){
                        returnString+=coefString;
                    }else{
                        returnString+="+"+coefString;
                    }
                }
            }else if(coefString.front()=='-'){
                if(typeTag(this->leadingCoefficient(x))=="rational"){
                    returnString+="-("
                        +Generic::expressionString
                        (Generic::negate(this->leadingCoefficient(x)))
                        +")";
                }else{
                    if(Generic::isEqu(this->leadingCoefficient(x),Generic::makeNumber(-1))
                       && this->polynomialOrder(x)!=makeLeaf(0)){
                        returnString+="-";
                    }else{
                        returnString+=coefString;
                    }
                }
            }else{
                if(typeTag(this->leadingCoefficient(x))=="rational"){
                    returnString+="+("+coefString+")";
                }else{
                    if(Generic::isEqu(this->leadingCoefficient(x),Generic::makeNumber(1))
                   && this->polynomialOrder(x)!=makeLeaf(0)){
                        returnString+="+";
                    }else{
                        returnString+="+"+coefString;
                }
                }
            }
           
            if(this->polynomialOrder(x)!=makeLeaf(0)){
                returnString+=listString(this->variable(x));
                if(this->polynomialOrder(x)!=makeLeaf(1)){
                    returnString+="^"+listString(this->polynomialOrder(x));
                }
            }
        }

        return(makeLeaf
               (returnString
                +this->expressionString
                (this->makePolynomial
                 (this->variable(x),Generic::restTerms(this->termList(x))))
                ->getItem()));
    }
   
    const TagType getTag(void)const{return(this->tagString);}
   
    virtual const List tag(const List& x)const
    {return(attachTag(this->getTag(),x));}
   
private:
    const TagType tagString;
    const SparseTermList* _sparseTermList;
    const DenseTermList* _denseTermList;
};

PolynomialArithmetic* _polynomialPackage(nullptr);

void installPolynomialPackage(void){
    _polynomialPackage=new PolynomialArithmetic();
}

void uninstallPolynomialPackage(void){
    if(nullptr!=_polynomialPackage) delete _polynomialPackage;
}

const List dense2Sparse(const List& denseTermList,
                        const List& dummy=makeList())
{
    const function<List(List,List)> denseTerm2SparseTerm
        =[](const List& denseTerm, const List& termOrder){
        return(makeList(termOrder,denseTerm));
    };
    const function<bool(List)> nonZeroCriterion
        =[](const List& sparseTerm){
        return(!Generic::isZero(cadr(sparseTerm)));
    };
    return(Generic::makeSparseTermList
           (filter
            (nonZeroCriterion,
             mapping(denseTerm2SparseTerm,
                     contents(denseTermList),
                     reverse
                     (enumerateInterval
                      (0,
                       value<int>(Generic::termListOrder(denseTermList))))))));

}

const List drop(const List& x){
    if(typeTag(x)=="complex"
       && Generic::isZero(Generic::imagPart(x))){
        return(drop(Generic::realPart(x)));
    }
    if(typeTag(x)=="real" && isInteger(contents(x))){
        return(real2Number(x));
    }
    if(typeTag(x)=="rational"
       && Generic::isEqu(Generic::denominator(x),Generic::makeNumber(1))){
        return(rational2Number(x));
    }
    if(typeTag(x)=="polynomial"){
        if(Generic::isZero(x)){
            return(Generic::makeNumber(0));
        }else if(Generic::isConstant(x)){
            return(Generic::leadingCoefficient(x));
        }
    }
    return(x);
}


void installCoercion(void)
{
    //raise
    putCoercion("number","rational",
                makeLeaf(function<List(List,List)>(number2Rational)));
    putCoercion("number","real",
                makeLeaf(function<List(List,List)>(number2Real)));
    putCoercion("number","complex",
                makeLeaf(function<List(List,List)>(number2Complex)));
    putCoercion("number","polynomial",
                makeLeaf(function<List(List,List)>(number2Polynomial)));
    putCoercion("rational","real",
                makeLeaf(function<List(List,List)>(rational2Real)));
    putCoercion("rational","complex",
                 makeLeaf(function<List(List,List)>(rational2Complex)));
    putCoercion("rational","polynomial",
                 makeLeaf(function<List(List,List)>(number2Polynomial)));
    putCoercion("real","complex",
                 makeLeaf(function<List(List,List)>(real2Complex)));
    putCoercion("real","polynomial",
                 makeLeaf(function<List(List,List)>(number2Polynomial)));
    putCoercion("dense","sparse",
                 makeLeaf(function<List(List,List)>(dense2Sparse)));
}


//---------abstraction barrier---------


int main(int argc, char** argv)
{
    installNumberPackage();
    installRationalPackage();
    installRealPackage();
    installComplexPackage();
    installPolynomialPackage();
    installCoercion();

    using namespace Generic;

    cout<<"Excersize 2.89 & 90:"<<endl;

    const List p1(makePolynomial
                  ("x",makeSparseTermList
                   (makeList
                    (makeList(2,makeNumber(3)),
                     makeList(1,makeComplexFromRealImag(2,3)),
                     makeList(0,makeNumber(7))))));
    const List p2(makePolynomial
                  ("x",makeSparseTermList
                   (makeList
                    (makeList(4,makeNumber(1)),
                     makeList(2,makeRational(2,3)),
                     makeList(0,makeComplexFromRealImag(5,3))
                     ))));
    cout<<"p1 = "<<expressionString(p1)<<endl;
    cout<<"p2 = "<<expressionString(p2)<<endl;
    cout<<"(add p1 p2) = "<<expressionString(add(p1,p2))<<endl;
    cout<<"(mul p1 p2) = "<<expressionString(mul(p1,p2))<<endl;

    cout<<endl;
    const List p1Dense(makePolynomial
                       ("x",makeDenseTermList
                        (makeList
                         (makeNumber(3),
                          makeComplexFromRealImag(2,3),
                          makeNumber(7)))));
    const List p2Dense(makePolynomial
                       ("x",makeDenseTermList
                        (makeList
                         (makeNumber(1),
                          makeNumber(0),
                          makeRational(2,3),
                          makeNumber(0),
                          makeComplexFromRealImag(5,3))
                          )));
    cout<<"p1Dense = "<<expressionString(p1Dense)<<endl;
    cout<<"p2Dense = "<<expressionString(p2Dense)<<endl;
    cout<<"(add p1Dense p2Dense) = "<<expressionString(add(p1Dense,p2Dense))<<endl;
    cout<<"(mul p1Dense p2Dense) = "<<expressionString(mul(p1Dense,p2Dense))<<endl;
    cout<<"(add p1 p2Dense) = "<<expressionString(add(p1,p2Dense))<<endl;
    cout<<"(mul p1Dense p2) = "<<expressionString(mul(p1Dense,p2))<<endl;
    cout<<endl;

    const List py1(makePolynomial
                   ("y",
                    makeSparseTermList
                    (makeList
                     (makeList(1,makeNumber(1)),
                      makeList(0,makeNumber(1))))));
    const List py2(makePolynomial
                   ("y",
                    makeSparseTermList
                    (makeList
                     (makeList(2,makeNumber(1)),
                      makeList(0,makeNumber(1))))));
    const List py3(makePolynomial
                   ("y",
                    makeSparseTermList
                    (makeList
                     (makeList(1,makeNumber(1)),
                      makeList(0,makeNumber(-1))))));
    const List pxy1(makePolynomial
                    ("x",
                     makeDenseTermList
                     (makeList
                      (py1,py2,py3))));
    cout<<"pxy1 = "<<expressionString(pxy1)<<endl;
    const List py4(makePolynomial
                   ("y",
                    makeDenseTermList
                    (makeList(makeNumber(1),makeNumber(-2)))));
    const List py5(makePolynomial
                   ("y",
                    makeDenseTermList
                    (makeList(makeNumber(1),
                              makeNumber(0),
                              makeNumber(0),
                              makeNumber(7)))));
    const List pxy2(makePolynomial
                    ("x",
                     makeSparseTermList
                     (makeList
                      (makeList(1,py4),
                       makeList(0,py5)))));
    cout<<"pxy2 = "<<expressionString(pxy2)<<endl;
    cout<<"(mul pxy1 pxy2) = "<<expressionString(mul(pxy1,pxy2))<<endl;

    cout<<endl<<"Excersize 2.91:"<<endl;
    const List p3(makePolynomial
                  ("x",makeSparseTermList
                   (makeList
                    (makeList(2,makeNumber(2)),
                     makeList(1,makeNumber(1)),
                     makeList(0,makeNumber(1))))));
    const List p4(makePolynomial
                  ("x",makeSparseTermList
                   (makeList
                    (makeList(1,makeNumber(1)),
                     makeList(0,makeNumber(2))))));
    cout<<"p3 = "<<expressionString(p3)<<endl;
    cout<<"p4 = "<<expressionString(p4)<<endl;
    const auto divResult1(div(p3,p4));
    cout<<"(div p3 p4):"<<endl;
    cout<<"quotient = "<<expressionString(car(divResult1))<<endl;
    cout<<"residual = "<<expressionString(cadr(divResult1))<<endl;
    cout<<endl;

    const auto p3Dense(makePolynomial
                       ("x",makeDenseTermList
                        (makeList
                         (makeNumber(2),
                          makeNumber(1),
                          makeNumber(1)))));
    const auto p4Dense(makePolynomial
                       ("x",makeDenseTermList
                        (makeList
                         (makeNumber(1),
                          makeNumber(2)))));
    cout<<"p3Dense = "<<expressionString(p3Dense)<<endl;
    cout<<"p4Dense = "<<expressionString(p4Dense)<<endl;
    const auto divResult2(div(p3Dense,p4Dense));
    cout<<"(div p3Dense p4Dense):"<<endl;
    cout<<"quotient = "<<expressionString(car(divResult2))<<endl;
    cout<<"residual = "<<expressionString(cadr(divResult2))<<endl;

   
    uninstallNumberPackage();
    uninstallRationalPackage();
    uninstallRealPackage();
    uninstallComplexPackage();
    uninstallPolynomialPackage();
    return(0);
}
----
出力
----
Excersize 2.89 & 90:
p1 = 3x^2+(2+3i)x+7
p2 = x^4+(2/3)x^2+5+3i
(add p1 p2) = x^4+(11/3)x^2+(2+3i)x+12+3i
(mul p1 p2) = 3x^6+(2+3i)x^5+9x^4+(1.333333333333333+2i)x^3+(59/3+9i)x^2+(1+21i)x+35+21i

p1Dense = 3x^2+(2+3i)x+7
p2Dense = x^4+(2/3)x^2+5+3i
(add p1Dense p2Dense) = x^4+(11/3)x^2+(2+3i)x+12+3i
(mul p1Dense p2Dense) = 3x^6+(2+3i)x^5+9x^4+(1.333333333333333+2i)x^3+(59/3+9i)x^2+(1+21i)x+35+21i
(add p1 p2Dense) = x^4+(11/3)x^2+(2+3i)x+12+3i
(mul p1Dense p2) = 3x^6+(2+3i)x^5+9x^4+(1.333333333333333+2i)x^3+(59/3+9i)x^2+(1+21i)x+35+21i

pxy1 = (y+1)x^2+(y^2+1)x+y-1
pxy2 = (y-2)x+y^3+7
(mul pxy1 pxy2) = (y^2-y-2)x^3+(y^4+2y^3-2y^2+8y+5)x^2+(y^5+y^3+8y^2-3y+9)x+y^4-y^3+7y-7

Excersize 2.91:
p3 = 2x^2+x+1
p4 = x+2
(div p3 p4):
quotient = 2x-3
residual = 7

p3Dense = 2x^2+x+1
p4Dense = x+2
(div p3Dense p4Dense):
quotient = 2x-3
residual = 7

0 件のコメント :

コメントを投稿