Ev3: a Library for Symbolic Computation in C++ Using N-Ary Trees
Total Page:16
File Type:pdf, Size:1020Kb
Ev3: A Library for Symbolic Computation in C++ using n-ary Trees Leo Liberti LIX, Ecole´ Polytechnique, 91128 Palaiseau, France ([email protected]) 3 october 2003 Abstract Ev3 is a callable C++ library for performing symbolic computation (calculation of symbolic derivatives and various expression simplification). The purpose of this library is to furnish a fast means to use symbolic derivatives to third-party scientific software (e.g. nonlinear optimization, solution of nonlinear equations). It is small, easy to interface, even reasonably easy to change; it is written in C++ and the source code is available. One feature that makes Ev3 very efficient in algebraic manipulation is that the data structures are based on n-ary trees. 1 Introduction Computer Algebra Systems (CAS) have helped mathematicians, physicists, engineers and other scientists enormously since their appearance. CASes are extremely useful in performing complex symbolic calcu- lations quickly. They do not generally require particular programming skills, yet they manage to carry out numerical analysis, symbolic manipulation and graph plotting in 2 and 3 dimensions. The range of existing CASes is impressive, both commercially available (e.g. Mathematica, Maple, Matlab, Mathcad, Reduce, Mupad etc.) and as free software (e.g. Maxima, GAP, yacas, Singular, GiNaC etc.); however most of them (with the notable exception of GiNaC, see below) fall short on the external Application Programming Interface (API), i.e. it is difficult, or impossible in many cases, to create a program in a compiled language, say in C/C++ or Fortran, which can use the external CAS facilities. This is a serious hindrance for user applications with programming requirements that go beyond those offered by the CAS proprietary language, or for those applications that need to be coded in a compiled language for efficiency, but would still benefit from the CAS facilities. The need for CAS-type libraries designed to be used from an API arises as the complexity or the commercial viability of the application gets higher. Thus, having experienced the benefits of CASes from the command line, so to speak, users now want to incorporate these functionalities in their own programs. This paper presents Ev3, a callable C++ library designed to perform simple symbolic manipulation. “Simple” in this context means symbolic differentiation and various expression simplifications. Thus, Ev3 is very useful for those scientific applications that need to compute derivatives, like for example continuous nonlinear programming or nonlinear equation solving. The reason why we have chosen to keep Ev3 “simple”, i.e. to limit the range of symbolic algorithms included in Ev3, is that we expect advanced users to take the source code and modify it to suit their own needs. For example, if an application needs a symbolic integration routine, Ev3’s data structures and basic methods can be used as a starting point. We did our best in keeping Ev3’s source code small, readable, well structured and easily extendable. Ev3 can be downloaded from http://www.lix.polytechnique.fr/ liberti/Ev3-1.0.tar.gz. Ev3 records mathematical expressions in a tree-like data structure (called n-ary tree) where each node has an arbitrary number of direct subnodes. Monomials of all degrees (including constants) are represented by the leaf nodes of the tree, and mathematical operators by the intermediate nodes. Entire subexpressions can be easily changed, substituted or deleted. New expressions can be formed in a number of different ways. A “standard form” for expressions is defined in order to make simplification more effective. These are some of Ev3’s features: • based on n-ary trees; • every node in a tree can have a numeric multiplicative coefficient; • every leaf node in a tree can have a numeric exponent; • basic form of garbage collection via reference counter; • basic parser transforms strings in n-ary trees; • basic functionality: function evaluation, expression simplification, symbolic differentiation. The rest of this paper is organized as follows. In section 2 we review the current situation as regards some existing CASes and their ability to be used as a callable library for external applications. In section 3 we describe the most common data structures used for symbolic computation (namely, lists and binary and n-ary trees). In section 4 we describe Ev3’s object-oriented software architecture and implementation of the abstract data structure describing the n-ary tree. Finally, section 5 is a tutorial on the use of Ev3. 2 Review of Current Situation As has been mentioned in the introduction, it is difficult, or impossible in many cases, to use CAS functionality within a C++ program. In this section we describe the current situation with some existing symbolic computation packages. 2.1 Commercial CASes This list encompasses some of the most widespread commercial CASes. Although some of these CASes are distributed for free for non-commercial purposes (e.g. MuPad), they appear in this list because they do not abide by the “free software” rules involving distribution of the source code and copyrighting via the GNU Public License (GPL). • Mathematica. Mathematica offers some support for external programs wanting to use its features via the MathLink [Mathematica(2001)] mechanism. However, a kernel needs to be running on the local machine in order to use it. This has a number of disadvantages: – the produced executables are not portable, for they need to find a running Mathematica kernel in order to run; – there is some computational overhead involved in runtime linking with a running Mathematica kernel; – there is no significant computational speed to be gained from this exercise, as all the Mathe- matica instructions are carried out by the Mathematica kernel, not by the user executable. • Maple. Maple [Maple(2001)] is capable of translating its procedures and functions in C or Fortran, however it is not possible to export symbolic manipulation code, and there is no way to call a Maple library from C/C++/Fortran. 2 • Mathlab. Strictly speaking, MatLab does not do symbolic computation. However there are some symbolic computation extensions available for MatLab [Matlab(2001)] so it makes sense to include it in this list. MatLab external API works in much the same was as Mathematica’s does: on initialization, the external C/C++/Fortran program spawns a running MatLab process on the local machine, and sets up input/output pipes from it to the program [Matlab API(2001)]. The same comments given above for Mathematica also apply here. • Mathcad. Unfortunately, publically available documentation about MathCad is scarce. MathCad can link to Microsoft-compliant dynamic link libraries (DLL) at runtime, and it would seem like it is also possible to do the reverse, i.e. use an external C++ driver program to use MathCad facilities; however the exact mechanism by which this is implemented seems to be a proprietary piece of information, and hence we cannot comment on it. • Reduce. The commercial distribution of Reduce includes the full source code (in standard Lisp), so it would seem feasible to try to compile the Lisp source code to an object file that would then be linked against a C/C++/Fortran driver program; however, this would fall into a “hacking trick” category more than into established use; moreover, this is true for each CAS that comes with source code. In practice, Reduce has no native mechanism for allowing easy linking with C/C++/Fortran programs, although it does have a facility for writing out its functions/procedure to C/Fortran code (with no symbolic computation). • MuPad. MuPad allows linking of external compiled binary modules via an API, however it is not possible to do the reverse, i.e. use MuPad’s facilities within an external C/C++/Fortran driver pro- gram [MuPad(2001), MuPad Documentation(2001)]. MuPad can export its functions/procedures to C/Fortran code (with no symbolic computation). 2.2 Free Software CASes This list comprises some of the most widespread general-purpose “free software” CASes. In all cases, the source code is available. Packages like GAP [GAP(2001)] or Singular [Singular(2001)] do not appear here because they are too specific in nature. SciLab [SciLab(2001)] does not appear because although it offers some runtime dynamic linking from C/C++/Fortran compiled code, its symbolic capabilities are only present when interfacing through Maple, i.e. symbolic computation within SciLab is actually carried out by Maple. Octave [Octave(2001)], like SciLab, does not have built-in symbolic computation facilities, although it does have a library that external program can link against. • Maxima. Maxima [Maxima(2001)] is a version of the MIT-developed MACSYMA system, modifed to run under GNU Common LISP. It is a wholly interactive system, and it has no support for external linking. • JACAL. JACAL [JACAL(2001)] is a symbolic mathematics system for the simplification and manipulation of equations and single and multiple valued algebraic expressions, written in Scheme. It has no support for external linking. • yacas. Yacas (Yet Another CAS, [yacas(2001)]) is a small computer algebra system based on a lisp interpreter. It can run in “web server mode”, so that any client can connect remotely and perform calculations. Data are passed back and forth via the http protocol. In this sense, it would be possible to implement a C/C++/Fortran client code. However, no local binary linking is possible. • GiNaC. The acronym stands for GiNaC is Not a CAS [GiNaC(2001)], and indeed this package keeps its promise. It is a library for doing symbolic computation (see [BFK01]); it is coded in C++ and designed to be used from C++. Symbolic computation performed by GiNaC extends to symbolic manipulation and symbolic differentiation, but it does not include symbolic integration or an algorithm for automatic simplification of symbolic expression (the authors argue that there is no such thing as a “standard for simplifying expressions”, so the way to carry it out is best left 3 to the user).