From: Richard Kreckel Date: Mon, 22 Nov 1999 18:24:16 +0000 (+0000) Subject: - One more hyperclever example and two more fixed from Alex' list. X-Git-Tag: release_0-5-0~141 X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=commitdiff_plain;h=37e5aa4df057ddc889c3c02335ab7d94b55b2106 - One more hyperclever example and two more fixed from Alex' list. --- diff --git a/doc/tutorial/tutorial.sgml.in b/doc/tutorial/tutorial.sgml.in index e2acbc49..3869936c 100644 --- a/doc/tutorial/tutorial.sgml.in +++ b/doc/tutorial/tutorial.sgml.in @@ -124,8 +124,8 @@ int main() Assuming the file is called hello.cc, on our system we can compile and run it like this: -sysprompt> c++ hello.cc -o hello -lcln -lginac -sysprompt> ./hello +$ c++ hello.cc -o hello -lcln -lginac +$ ./hello 355687428096000*x*y+20922789888000*y^2+6402373705728000*x^2 @@ -305,7 +305,7 @@ x^(-1)-1/3*x+Order(x^2) easily installed on your system by three steps: configuration, build, installation. -Prerequistes +Prerequistes In order to install GiNaC on your system, some prerequistes need to be met. First of all, you need to have a C++-compiler adhering to @@ -404,18 +404,18 @@ your login shell.) configure-script Simple configuration for a site-wide GiNaC library assuming everything is in default paths: -sysprompt> export CXXFLAGS="-Wall -O2" -sysprompt> ./configure --enable-shared +$ export CXXFLAGS="-Wall -O2" +$ ./configure -Configuration for a private GiNaC library with several +Configuration for a private static GiNaC library with several components sitting in custom places (site-wide GCC and private CLN): -sysprompt> export CXX=/usr/local/gnu/bin/c++ -sysprompt> export CPPFLAGS="${CPPFLAGS} -I${HOME}/include" -sysprompt> export CXXFLAGS="${CXXFLAGS} -ggdb -Wall -ansi -pedantic -O2" -sysprompt> export LDFLAGS="${LDFLAGS} -L${HOME}/lib" -sysprompt> ./configure --enable-shared --prefix=${HOME} +$ export CXX=/usr/local/gnu/bin/c++ +$ export CPPFLAGS="${CPPFLAGS} -I${HOME}/include" +$ export CXXFLAGS="${CXXFLAGS} -ggdb -Wall -ansi -pedantic -O2" +$ export LDFLAGS="${LDFLAGS} -L${HOME}/lib" +$ ./configure --disable-shared --prefix=${HOME} @@ -433,11 +433,11 @@ suite by typing make check. This will compile some sample programs, run them and compare the output to reference output. Each of the checks should return a message passed together with the CPU time used for that particular test. If it does -not, something went wrong. This is mostly intended to be a check if -something was broken during the development, but not a sanity check of -your system. Another intent is to allow people to fiddle around with -optimization. If CLN was installed all right this -step is unlikely to return any errors. +not, something went wrong. This is mostly intended to be a QA-check +if something was broken during the development, but not a sanity check +of your system. Another intent is to allow people to fiddle around +with optimization. If CLN was installed all right +this step is unlikely to return any errors. @@ -687,15 +687,20 @@ interpretation differs. Symbols Symbols are for symbolic manipulation what atoms are for -chemistry. You can declare objects of type symbol as any other object -simply by saying symbol x,y;. There is, however, a -catch in here having to do with the fact that C++ is a compiled -language. The information about the symbol's name is thrown away by -the compiler but at a later stage you may want to print expressions -holding your symbols. In order to avoid confusion GiNaC's symbols are -able to know their own name. This is accomplished by declaring its -name for output at construction time in the fashion symbol -x("x");. +chemistry. You can declare objects of class symbol +as any other object simply by saying symbol x,y;. +There is, however, a catch in here having to do with the fact that C++ +is a compiled language. The information about the symbol's name is +thrown away by the compiler but at a later stage you may want to print +expressions holding your symbols. In order to avoid confusion GiNaC's +symbols are able to know their own name. This is accomplished by +declaring its name for output at construction time in the fashion +symbol x("x");. If you declare a symbol using the +default constructor (i.e. without string-argument) the system will +deal out a unique name. That name may not be suitable for printing +but for internal routines when no output is desired it is often +enough. We'll come across examples of such symbols later in this +tutorial. Although symbols can be assigned expressions for internal reasons, you should not do it (and we are not going to tell you how it @@ -1042,7 +1047,7 @@ explicitly, results in the same canonical form. Built-in Functions -This chapter is not here yet +This section is not here yet @@ -1187,7 +1192,7 @@ not within the user's sphere of influence. -Polynomial Arithmetic +Polynomial Arithmetic GCD and LCM @@ -1237,11 +1242,38 @@ int main() The <function>normal</function> method While in common symbolic code gcd() and -lcm() are not too heavily used, some basic -simplification occurs frequently. Therefore -.normal(), which provides some basic form of -simplification, has become a method of class ex, -just like .expand(). +lcm() are not too heavily used, simplification +occurs frequently. Therefore .normal(), which +provides some basic form of simplification, has become a method of +class ex, just like .expand(). +It converts a rational function into an equivalent rational function +where numererator and denominator are coprime. This means, it finds +the GCD of numerator and denominator and cancels it. If it encounters +some object which does not belong to the domain of rationals (a +function for instance), that object is replaced by a temporary symbol. +This means that both expressions t1 and +t2 are indeed simplified in this little program: +Cancellation of polynomial GCD (with obstacles) + +#include <ginac/ginac.h> +using namespace GiNaC; + +int main() +{ + symbol x("x"); + ex t1 = (pow(x,2) + 2*x + 1)/(x + 1); + ex t2 = (pow(sin(x),2) + 2*sin(x) + 1)/(sin(x) + 1); + cout << "t1 is " << t1.normal() << endl; + cout << "t2 is " << t2.normal() << endl; + // ... +} + + + +Of course this works for multivariate polynomials too, so the ratio of +the sample-polynomials from the section about GCD and LCM above would +be normalized to P_a/P_b = +(4*y+z)/(y+3*z). @@ -1249,7 +1281,9 @@ just like .expand(). Symbolic Differentiation - +GiNaC's objects know how to differentiate themselves. Thus, a +polynomial (class add) knows that its derivative is +the sum of the derivatives of all the monomials: Simple polynomial differentiation #include <ginac/ginac.h> @@ -1267,21 +1301,48 @@ int main() } - - - -Differentiation with nontrivial functions +If a second integer parameter n is given the +diff method returns the nth +derivative. + +If every object and every function is told +what its derivative is, all derivatives of composed objects can be +calculated using the chain rule and the product rule. Consider, for +instance the expression 1/cosh(x). Since the +derivative of cosh(x) is sinh(x) +and the derivative of pow(x,-1) is +-pow(x,-2) GiNaC can readily compute the +composition. It turns out that the composition is the generating +function for Euler Numbers, i.e. the so called +nth Euler number is the coefficient of +x^n/n! in the expansion of +1/cosh(x). We may use this identity to code a +function that generates Euler numbers in just three lines: +Differentiation with nontrivial functions: Euler numbers #include <ginac/ginac.h> using namespace GiNaC; +ex EulerNumber(unsigned n) +{ + symbol x; + ex generator = pow(cosh(x),-1); + return generator.diff(x,n).subs(x==0); +} + int main() { - // To Be Done... + for (unsigned i=0; i<11; i+=2) + cout << EulerNumber(i) << endl; + return 0; } - +When you run it, it produces the sequence 1, +-1, 5, -61, +1385, -50521. We increment the +loop variable i by two since all odd Euler numbers +vanish anyways. @@ -1311,7 +1372,7 @@ int main() MySeries = MyExpr2.series(x, point, 7); cout << MyExpr2 << " == " << MySeries << " for small " << x << endl; - \\ ... + // ... } @@ -1324,8 +1385,8 @@ wonderful formula Pi==16*atan(1/5)-4*atan(1/239). We may expand the arcus tangent around 0 and insert the fractions 1/5 and 1/239. But, as we have seen, a series in GiNaC carries an order term with it. -The preprocessor-macro series_to_poly may be used -to strip this off: +The function series_to_poly may be used to strip +this off: Series expansion using Méchain's formula for <literal>Pi</literal> @@ -1593,24 +1654,4 @@ language. - - -Index - - - CLN - obtaining - - - - gcd - - - - lcm - gcd - - - -