GiNaC порядок вывода

Я строю приложение, написанное на C++, которое в значительной степени включает алгебру. Я решил использовать GiNaC для системы компьютерной алгебры (CAS). Она работает отлично; Однако есть небольшая проблема. Порядок элементов не такой, каким я хочу, чтобы они были в выводе. Позвольте мне привести пример. Это мой код C++:

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

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

    std::cout << poly;
}

Выход этой программы:

5+x^2+3*x

Ну, я обнаружил, что это не является постоянным, выход также может быть:

5+3*x+x^2

Хотя, оба математически правильные формы, которую я хочу (или, может быть, мне нужно:-) ни один из них. Я хочу, чтобы полином начинался с наибольшей степени, т.е. мой вывод должен быть:

x^2+3*x+5

Эта проблема еще хуже, когда мы добавляем числа со знаком, парантез или более сложное алгебраическое выражение (иногда даже пишем (-3+a)x, что выглядит очень некрасиво:-) std::cout<<GiNaC::latexне решает проблему. И, на мой взгляд, самая раздражающая часть - это неустойчивое поведение результатов.
Возможно ли что-то подобное в GiNaC. Я также не хочу иметь действительно грязный код (потому что C++0x <regex> библиотека может сделать это легко, но я бы не хотел использовать регулярные выражения, мой код достаточно сложный)
Я использую GCC 4.7.2 под Ubuntu Quantal Quetzal. Спасибо за помощь.

1 ответ

Решение

Поведение, на которое вы ссылаетесь, документировано здесь, и это не похоже на встроенную функциональность для обработки этого случая.

В соответствии с этим вам необходимо реализовать это самостоятельно. Ниже приведен краткий пример кода, как это можно сделать.

#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;
}
Другие вопросы по тегам