C++符号计算库GiNaC的安装和使用教程

16 篇文章 4 订阅

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

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值