manpagez: man pages & more
info ginac
Home | html | info | man
[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.15.1 Expression output

Expressions can simply be written to any stream:

 
{
    symbol x("x");
    ex e = 4.5*I+pow(x,2)*3/2;
    cout << e << endl;    // prints '4.5*I+3/2*x^2'
    // ...

The default output format is identical to the ginsh input syntax and to that used by most computer algebra systems, but not directly pastable into a GiNaC C++ program (note that in the above example, pow(x,2) is printed as ‘x^2’).

It is possible to print expressions in a number of different formats with a set of stream manipulators;

 
std::ostream & dflt(std::ostream & os);
std::ostream & latex(std::ostream & os);
std::ostream & tree(std::ostream & os);
std::ostream & csrc(std::ostream & os);
std::ostream & csrc_float(std::ostream & os);
std::ostream & csrc_double(std::ostream & os);
std::ostream & csrc_cl_N(std::ostream & os);
std::ostream & index_dimensions(std::ostream & os);
std::ostream & no_index_dimensions(std::ostream & os);

The tree, latex and csrc formats are also available in ginsh via the print(), print_latex() and print_csrc() functions, respectively.

All manipulators affect the stream state permanently. To reset the output format to the default, use the dflt manipulator:

 
    // ...
    cout << latex;            // all output to cout will be in LaTeX format from
                              // now on
    cout << e << endl;        // prints '4.5 i+\frac{3}{2} x^{2}'
    cout << sin(x/2) << endl; // prints '\sin(\frac{1}{2} x)'
    cout << dflt;             // revert to default output format
    cout << e << endl;        // prints '4.5*I+3/2*x^2'
    // ...

If you don't want to affect the format of the stream you're working with, you can output to a temporary ostringstream like this:

 
    // ...
    ostringstream s;
    s << latex << e;         // format of cout remains unchanged
    cout << s.str() << endl; // prints '4.5 i+\frac{3}{2} x^{2}'
    // ...

The csrc (an alias for csrc_double), csrc_float, csrc_double and csrc_cl_N manipulators set the output to a format that can be directly used in a C or C++ program. The three possible formats select the data types used for numbers (csrc_cl_N uses the classes provided by the CLN library):

 
    // ...
    cout << "f = " << csrc_float << e << ";\n";
    cout << "d = " << csrc_double << e << ";\n";
    cout << "n = " << csrc_cl_N << e << ";\n";
    // ...

The above example will produce (note the x^2 being converted to x*x):

 
f = (3.0/2.0)*(x*x)+std::complex<float>(0.0,4.5000000e+00);
d = (3.0/2.0)*(x*x)+std::complex<double>(0.0,4.5000000000000000e+00);
n = cln::cl_RA("3/2")*(x*x)+cln::complex(cln::cl_I("0"),cln::cl_F("4.5_17"));

The tree manipulator allows dumping the internal structure of an expression for debugging purposes:

 
    // ...
    cout << tree << e;
}

produces

 
add, hash=0x0, flags=0x3, nops=2
    power, hash=0x0, flags=0x3, nops=2
        x (symbol), serial=0, hash=0xc8d5bcdd, flags=0xf
        2 (numeric), hash=0x6526b0fa, flags=0xf
    3/2 (numeric), hash=0xf9828fbd, flags=0xf
    -----
    overall_coeff
    4.5L0i (numeric), hash=0xa40a97e0, flags=0xf
    =====

The latex output format is for LaTeX parsing in mathematical mode. It is rather similar to the default format but provides some braces needed by LaTeX for delimiting boxes and also converts some common objects to conventional LaTeX names. It is possible to give symbols a special name for LaTeX output by supplying it as a second argument to the symbol constructor.

For example, the code snippet

 
{
    symbol x("x", "\\circ");
    ex e = lgamma(x).series(x==0,3);
    cout << latex << e << endl;
}

will print

 
    {(-\ln(\circ))}+{(-\gamma_E)} \circ+{(\frac{1}{12} \pi^{2})} \circ^{2}
    +\mathcal{O}(\circ^{3})

Index dimensions are normally hidden in the output. To make them visible, use the index_dimensions manipulator. The dimensions will be written in square brackets behind each index value in the default and LaTeX output formats:

 
{
    symbol x("x"), y("y");
    varidx mu(symbol("mu"), 4), nu(symbol("nu"), 4);
    ex e = indexed(x, mu) * indexed(y, nu);

    cout << e << endl;
     // prints 'x~mu*y~nu'
    cout << index_dimensions << e << endl;
     // prints 'x~mu[4]*y~nu[4]'
    cout << no_index_dimensions << e << endl;
     // prints 'x~mu*y~nu'
}

If you need any fancy special output format, e.g. for interfacing GiNaC with other algebra systems or for producing code for different programming languages, you can always traverse the expression tree yourself:

 
static void my_print(const ex & e)
{
    if (is_a<function>(e))
        cout << ex_to<function>(e).get_name();
    else
        cout << ex_to<basic>(e).class_name();
    cout << "(";
    size_t n = e.nops();
    if (n)
        for (size_t i=0; i<n; i++) {
            my_print(e.op(i));
            if (i != n-1)
                cout << ",";
        }
    else
        cout << e;
    cout << ")";
}

int main()
{
    my_print(pow(3, x) - 2 * sin(y / Pi)); cout << endl;
    return 0;
}

This will produce

 
add(power(numeric(3),symbol(x)),mul(sin(mul(power(constant(Pi),numeric(-1)),
symbol(y))),numeric(-2)))

If you need an output format that makes it possible to accurately reconstruct an expression by feeding the output to a suitable parser or object factory, you should consider storing the expression in an archive object and reading the object properties from there. See the section on archiving for more information.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]
© manpagez.com 2000-2024
Individual documents may contain additional copyright information.