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

4.9 Lists of expressions

The GiNaC class lst serves for holding a list of arbitrary expressions. They are not as ubiquitous as in many other computer algebra packages, but are sometimes used to supply a variable number of arguments of the same type to GiNaC methods such as subs() and some matrix constructors, so you should have a basic understanding of them.

Lists can be constructed by assigning a comma-separated sequence of expressions:

 
{
    symbol x("x"), y("y");
    lst l;
    l = x, 2, y, x+y;
    // now, l is a list holding the expressions 'x', '2', 'y', and 'x+y',
    // in that order
    ...

There are also constructors that allow direct creation of lists of up to 16 expressions, which is often more convenient but slightly less efficient:

 
    ...
    // This produces the same list 'l' as above:
    // lst l(x, 2, y, x+y);
    // lst l = lst(x, 2, y, x+y);
    ...

Use the nops() method to determine the size (number of expressions) of a list and the op() method or the [] operator to access individual elements:

 
    ...
    cout << l.nops() << endl;                // prints '4'
    cout << l.op(2) << " " << l[0] << endl;  // prints 'y x'
    ...

As with the standard list<T> container, accessing random elements of a lst is generally an operation of order O(N). Faster read-only sequential access to the elements of a list is possible with the iterator types provided by the lst class:

 
typedef ... lst::const_iterator;
typedef ... lst::const_reverse_iterator;
lst::const_iterator lst::begin() const;
lst::const_iterator lst::end() const;
lst::const_reverse_iterator lst::rbegin() const;
lst::const_reverse_iterator lst::rend() const;

For example, to print the elements of a list individually you can use:

 
    ...
    // O(N)
    for (lst::const_iterator i = l.begin(); i != l.end(); ++i)
        cout << *i << endl;
    ...

which is one order faster than

 
    ...
    // O(N^2)
    for (size_t i = 0; i < l.nops(); ++i)
        cout << l.op(i) << endl;
    ...

These iterators also allow you to use some of the algorithms provided by the C++ standard library:

 
    ...
    // print the elements of the list (requires #include <iterator>)
    std::copy(l.begin(), l.end(), ostream_iterator<ex>(cout, "\n"));

    // sum up the elements of the list (requires #include <numeric>)
    ex sum = std::accumulate(l.begin(), l.end(), ex(0));
    cout << sum << endl;  // prints '2+2*x+2*y'
    ...

lst is one of the few GiNaC classes that allow in-place modifications (the only other one is matrix). You can modify single elements:

 
    ...
    l[1] = 42;       // l is now {x, 42, y, x+y}
    l.let_op(1) = 7; // l is now {x, 7, y, x+y}
    ...

You can append or prepend an expression to a list with the append() and prepend() methods:

 
    ...
    l.append(4*x);   // l is now {x, 7, y, x+y, 4*x}
    l.prepend(0);    // l is now {0, x, 7, y, x+y, 4*x}
    ...

You can remove the first or last element of a list with remove_first() and remove_last():

 
    ...
    l.remove_first();   // l is now {x, 7, y, x+y, 4*x}
    l.remove_last();    // l is now {x, 7, y, x+y}
    ...

You can remove all the elements of a list with remove_all():

 
    ...
    l.remove_all();     // l is now empty
    ...

You can bring the elements of a list into a canonical order with sort():

 
    ...
    lst l1, l2;
    l1 = x, 2, y, x+y;
    l2 = 2, x+y, x, y;
    l1.sort();
    l2.sort();
    // l1 and l2 are now equal
    ...

Finally, you can remove all but the first element of consecutive groups of elements with unique():

 
    ...
    lst l3;
    l3 = x, 2, 2, 2, y, x+y, y+x;
    l3.unique();        // l3 is now {x, 2, y, x+y}
}

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