C++符号计算库GiNaC的安装和使用教程
C++符号计算库GiNaC的安装和使用教程GIAC是一个C++库.它被设计成方便用户在一个符号计算系统下创建自定义的集成系统,比如将符号操作与计算机科学的更成熟领域(如计算密集型数值应用程序、图形界面等)集成在一起.它是根据GNU通用公共许可证(GPL)的条款和条件分发的(它的开发小组也是极力反对软件专利制度的).GiNaC是一个迭代和递归的缩写:GiNaC is Not a CAS(CAS代表计
C++符号计算库GiNaC的安装和使用教程
GiNaC是一个C++库.它被设计成方便用户在一个符号计算系统下创建自定义的集成系统,比如将符号操作与计算机科学的更成熟领域(如计算密集型数值应用程序、图形界面等)集成在一起.它是根据GNU通用公共许可证(GPL)的条款和条件分发的(它的开发小组也是极力反对软件专利制度的).GiNaC是一个迭代和递归的缩写:GiNaC is Not a CAS(CAS代表计算机代数系统),是不是有GNU(GNU’s not Unix)那味儿了.
GiNaC最初的动机是被开发为xloops的替代引擎,目前由Maple CAS提供支持.然而,它并不局限于高能物理的应用.它的设计在某种意义上是革命性的,它与其他CAS相反,它不试图提供广泛的代数能力和简单的脚本交互式编程语言,而是接受给定的语言(C++)并通过后续二次开发的代数功能来扩展它.
GiNaC的安装
首先你需要有GNU g++ 4.8.1以上,sed,还有make(这些都没有还是退群算了).然后就是先安装CLN:一个c++的基础数值/符号库.先在这里下载CLN的源代码包,然后我们来编译:
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
反正我在安装CLN过程中没遇到什么问题,那么接下来下载GiNac的源代码包,然后我们来编译:
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
注意:这里make的时候有可能报错:
...
/bin/bash: no-split: command not found
...
但是等会儿make check的时候发现全都pass了,所以无所谓,估计是文档编译的error不影响功能;
GiNaC的使用
我们用官方文档编译test的时候会出现error while loading shared libraries错误,因此我们先解决这个错误(默认情况下,编译器只会使用/lib和/usr/lib这两个目录下的库文件,通常通过源码包进行安装时,如果不指定–prefix,会将库安装在/usr/local/lib目录下;当运行程序需要链接动态库时,提示找不到相关的.so库,会报错.也就是说,/usr/local/lib目录不在系统默认的库搜索目录中,需要将目录加进去.):
root@hanss-S1-Pro-Series:/MyPath# vim /etc/ld.so.conf
然后添加上"/usr/local/lib"后保存退出:
include ld.so.conf.d/*.conf
/usr/local/lib
最后再刷新一下链接库的缓存即可(注意有新的文件加入/usr/local/lib还得刷新):
root@hanss-S1-Pro-Series:/MyPath# /sbin/ldconfig -v
然后搞个测试程序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;
}
编译运行:
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
老实说GiNac有许多好用的基础功能,比如多项式表达/多项式的GCD和LCM/代数式替换,可以在这个基础上打造更复杂的符号计算:
多项式表达
// 多项式表达
#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
多项式的GCD和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
}
多项式的符号替换
// 多项式的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
}
引用:
[1] CLN: https://www.ginac.de/CLN
[2] GiNac: https://www.ginac.de
![Logo](https://devpress.csdnimg.cn/79de2bf0b7994defa4242ef90d5513fa.jpg)
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)