Question

I am building an application written in C++, that heavily involves algebra. I decided to use GiNaC for Computer Algebra System (CAS) It is working perfectly; however there is a little problem. The order of the elements are not how I want them to be in output. Let me give an example. This is my C++ code:

#include <iostream>
#include <ginac/ginac.h>

int main()
{
    using namespace GiNaC;
    symbol x("x");
    ex poly((x^2)+3*x+5);

    std::cout << poly;
}

Output of this program is:

5+x^2+3*x

Well, I detected that this is not constant, the output ALSO can be:

5+3*x+x^2

Although, both are mathematically correct the form I want (or maybe I need :-) is neither of them. I want the polynomial to start with the biggest degree, i.e my output should be:

x^2+3*x+5

This problem is even worse when we add signed numbers, paranthesis or more complex algebraic expression (it sometimes even write (-3+a)x which looks very ugly :-) std::cout<<GiNaC::latex does not fix the problem. And in my point of view, the most annoying part is the erratic behaviour of the output.
Is something like that possible in GiNaC. I also don't want to have a really messy code (because C++0x <regex> library can do this easily, but I would rather not involve regular expression, my code is complex enough)
I am using GCC 4.7.2 under Ubuntu Quantal Quetzal. Thank you for your help.

Was it helpful?

Solution

The behavior you are referring to is documented here, and it doesn't seem to be any builtin functionality for handling this case.

According to this you need to implement this yourself. Below is a short example code of how this can be done.

#include <iostream>
#include <vector>
#include <algorithm>
#include <ginac/ginac.h>

int main()
{
    using namespace GiNaC;
    symbol x("x");
    ex poly(-3*x-5+power(x,2));

    std::vector<ex> terms(poly.begin(), poly.end());
    std::sort(std::begin(terms), std::end(terms), 
        [x](const ex& lhs, const ex& rhs) { return lhs.degree(x)>rhs.degree(x); });

    bool first{ true };
    for(auto term : terms) {
        if( first ) first = false;
        else if( term.coeff(term)>0) std::cout << '+' ;

        std::cout << term;
    }

    std::cout << std::endl;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top