Installation and usage tutorial of C++ symbolic computing library GiNaC

Installation and usage tutorial of C++ symbolic computing library GiNaC


GiNaC is a C++ library. It is designed to facilitate users to create custom integrated systems under a symbolic computing system, such as integrating symbolic operations with more mature areas of computer science (such as computationally intensive numerical applications, graphical interfaces, etc.) together. It is distributed under the terms and conditions of the GNU General Public License (GPL) ( its development team is also vehemently opposed to the software patent system). GiNaC is an acronym for iterative and recursive: G iNaC is N ot a C AS (CAS stands for Computer Algebra System), does it have the flavor of GNU (GNU's not Unix)?

insert image description here

GiNaC was originally motivated to be developed as a replacement engine for xloops, currently powered by Maple CAS. However, it is not limited to applications in high energy physics. Its design is revolutionary in the sense that it is contrary to other CAS , it does not try to provide extensive algebraic capabilities and a simple scripted interactive programming language, but accepts a given language (C++) and extends it with algebraic capabilities for subsequent secondary development.

Installation of GiNaC

First of all, you need to have GNU g++ 4.8.1 or above, sed, and make (if you don’t have these, you should leave the group). Then you need to install CLN: a basic value/symbol library for c++. Download the source code of CLN here package , and then we compile:

root@hanss-S1-Pro-Series:/MyPath# tar -jvxf cln-1.3.6.tar.bz2
root@hanss-S1-Pro-Series:/MyPath# cd cln-1.3.6
root@hanss-S1-Pro-Series:/MyPath# ./configure
root@hanss-S1-Pro-Series:/MyPath# make
root@hanss-S1-Pro-Series:/MyPath# make check
root@hanss-S1-Pro-Series:/MyPath# make install

Anyway, I didn't encounter any problems during the installation of CLN, so next download the source code package of GiNac , and then we will compile:

root@hanss-S1-Pro-Series:/MyPath# tar -jvxf ginac-1.8.0.tar.bz2
root@hanss-S1-Pro-Series:/MyPath# cd ginac-1.8.0
root@hanss-S1-Pro-Series:/MyPath# export CXXFLAGS="-Wall -O2"
root@hanss-S1-Pro-Series:/MyPath# ./configure
root@hanss-S1-Pro-Series:/MyPath# make
root@hanss-S1-Pro-Series:/MyPath# make check
root@hanss-S1-Pro-Series:/MyPath# make install

Note : There may be an error when making here:

...
/bin/bash: no-split: command not found
...

But when I make check later, I found that all passed, so it doesn't matter, it is estimated that the error of document compilation does not affect the function;

Use of GiNaC

When we compile the test with the official document , an error while loading shared libraries error will appear , so we first solve this error (by default, the compiler will only use the library files in the two directories /lib and /usr/lib, usually When installing through the source package, if –prefix is ​​not specified, the library will be installed in the /usr/local/lib directory; when the running program needs to link the dynamic library, it will prompt that the relevant .so library cannot be found, and an error will be reported. Also That is to say, the /usr/local/lib directory is not in the system's default library search directory, and the directory needs to be added.):

root@hanss-S1-Pro-Series:/MyPath# vim /etc/ld.so.conf

Then add "/usr/local/lib" and save and exit:

include ld.so.conf.d/*.conf
/usr/local/lib

Finally, just refresh the cache of the link library (note that new files are added to /usr/local/lib and have to be refreshed):

root@hanss-S1-Pro-Series:/MyPath# /sbin/ldconfig -v

Then make a test program hello.cc :

#include <iostream>
#include <ginac/ginac.h>
using namespace std;
using namespace GiNaC;
int main()
{
    
    
    symbol x("x"), y("y");
    ex poly;
    for (int i=0; i<3; ++i)
    poly += factorial(i+16)*pow(x,i)*pow(y,2-i);
    cout << poly << endl;
    return 0;
}

Compile and run:

root@hanss-S1-Pro-Series:/MyPath# g++ hello.cc -o hello -lginac -lcln
root@hanss-S1-Pro-Series:/MyPath# ./hello
355687428096000*x*y+20922789888000*y^2+6402373705728000*x^2

To be honest, GiNac has many useful basic functions, such as polynomial expression/polynomial GCD and LCM/algebraic replacement, which can create more complex symbolic calculations on this basis:

polynomial expression
// 多项式表达
#include <ginac/ginac.h>
using namespace GiNaC;
int main()
{
    
    
    symbol x("x"), y("y");
    ex PolyInp = 4*pow(x,3)*y + 5*x*pow(y,2) + 3*y- pow(x+y,2) + 2*pow(y+2,2) - 8;
    ex Poly = PolyInp.expand();
    for (int i=Poly.ldegree(x);i<=Poly.degree(x);++i) 
    {
    
    
        cout << "The x^" << i << "-coefficient is "<< Poly.coeff(x,i) << endl;
    }
    cout << "As polynomial in y: "<< Poly.collect(y) << endl;
}

// The x^0-coefficient is y^2+11*y
// The x^1-coefficient is 5*y^2-2*y
// The x^2-coefficient is -1
// The x^3-coefficient is 4*y
// As polynomial in y: -x^2+(5*x+1)*y^2+(-2*x+4*x^3+11)*y
Polynomial GCD and LCM
// 多项式的GCD和LCM
#include <ginac/ginac.h>
using namespace GiNaC;
int main()
{
    
    
    symbol x("x"), y("y"), z("z");
    ex P_a = 4*x*y + x*z + 20*pow(y, 2) + 21*y*z + 4*pow(z, 2);
    ex P_b = x*y + 3*x*z + 5*pow(y, 2) + 19*y*z + 12*pow(z, 2);
    ex P_gcd = gcd(P_a, P_b);
    // x + 5*y + 4*z
    ex P_lcm = lcm(P_a, P_b);
    // 4*x*y^2 + 13*y*x*z + 20*y^3 + 81*y^2*z + 67*y*z^2 + 3*x*z^2 + 12*z^3
}
Sign substitution for polynomials
// 多项式的GCD和LCM
#include <ginac/ginac.h>
using namespace GiNaC;
int main()
{
    
    
    symbol x("x"), y("y");
    ex e1 = 2*x*x-4*x+3;
    cout << "e1(7) = " << e1.subs(x == 7) << endl;
    // -> 73ex e2 = x*y + x;
    cout << "e2(-2, 4) = " << e2.subs(lst{
    
    x == -2, y == 4}) << endl;
    // -> -10
    cout << subs(a^2+b^2+(x+y)^2,$1^2==$1^3) << endl;
    // b^3+a^3+(x+y)^3
    cout << subs(a^4+b^4+(x+y)^4,$1^2==$1^3) << endl;
    // b^4+a^4+(x+y)^4
    cout << subs((a+b+c)^2,a+b==x) << endl;
    // (a+b+c)^2
    cout << subs((a+b+c)^2,a+b+$1==x+$1) << endl;
    // (x+c)^2
    cout << subs(a+2*b,a+b==x) << endl;
    // a+2*b
    cout << subs(4*x^3-2*x^2+5*x-1,x==a) << endl;
    // -1+5*a-2*a^2+4*a^3
    cout << subs(4*x^3-2*x^2+5*x-1,x^$0==a^$0) << endl;
    // -1+5*x-2*a^2+4*a^3
    cout << subs(sin(1+sin(x)),sin($1)==cos($1)) << endl;
    // cos(1+cos(x))
    cout << expand(subs(a*sin(x+y)^2+a*cos(x+y)^2+b,cos($1)^2==1-sin($1)^2)) << endl;
    // a+b
}

Quote:

[1] CLN: https://www.ginac.de/CLN

[2] GiNac: https://www.ginac.de

おすすめ

転載: blog.csdn.net/hanss2/article/details/115697449