4 Writing a C++ program to call giac

Now we are going to write a number of C++ programs, which calls Giac directly to do different math operations. All these programs are compiled using this makefile

4.1 Makefile

all:: main 
 
main: main.cc Makefile 
         -rm -f *.o 
         g++ -g main.cc -lgiac -lgmp -Wall -Wextra -Winit-self -Wold-style-cast\ 
         -Wuninitialized -Wmissing-declarations -pedantic\ 
         -fno-elide-constructors -pedantic-errors -Woverloaded-virtual\ 
         -Wstrict-aliasing  -std=c++17 -o main 
         
.PHONY: clean 
clean :: 
        -rm -f main.o
 

4.2 example 1. C++ program to do integration

This program calls giac to do \(\int {\sin (x),x}\). Create this C++ file

#include <iostream> 
#include <fstream> 
#include <sstream> 
#include <string> 
 
#include <giac/config.h> 
#include <giac/giac.h> 
 
using namespace std; 
 
int main() 
{ 
    giac::context ct; 
    std::string command="sin(x),x"; 
    giac::gen e(command,&ct); 
    e = giac::eval(e,1,&ct); 
    try 
    { 
        cout<<"inside try BEFORE calling "<< command <<endl; 
        giac::gen anti = _integrate(e,&ct); 
        cout<<"result of integrate: "<< anti <<endl; 
    } 
    catch (const std::exception &exc) 
    { 
        std::cout<<">>>>>>>>>>>>>> EXCEPTION HAPPENED "<< exc.what()<<std::endl; 
    } 
 
    return 0; 
}
 

Now compile and run the above file

>make -I$HOME all 
>./main 
inside try BEFORE calling sin(x),x 
result of integrate: -cos(x)
 

An alternative to the above, is to put the giac command directly in the string and this way no need to call _integrate as separate call. Like this

#include <iostream> 
#include <fstream> 
#include <sstream> 
#include <string> 
 
 
#include <giac/config.h> 
#include <giac/giac.h> 
 
using namespace std; 
 
int main() 
{ 
 
    giac::context ct; 
    std::string command="integrate(sin(x),x)"; 
    giac::gen e(command,&ct); 
    e = giac::eval(e,1,&ct); 
    cout<<"inside try BEFORE calling "<< command <<endl; 
    cout<<"result of integrate: "<< e <<endl; 
 
    return 0; 
}

Compile and run, it will give the same exact result. In the above  giac::eval did all the work. The above might be simpler way to do things.

4.3 example 2. C++ program to solve for roots of equation

This program calls giac to solve \(x^4-1=3\) for \(x\). Create this main.cc C++ file

#include <iostream> 
#include <fstream> 
#include <sstream> 
#include <string> 
 
 
#include <giac/config.h> 
#include <giac/giac.h> 
 
using namespace std; 
 
int main() 
{ 
 
    giac::context ct; 
 
    giac::eval( giac::gen("eq:=x^4-1=3",&ct) , 1, &ct); 
    giac::gen e = giac::eval( giac::gen("solve(eq,x)",&ct) , 1, &ct); 
 
    cout<<"The solution is " << e <<endl; 
 
    return 0; 
}

Compile and run

>make -I$HOME all 
>./main 
The solution is list[-4^(1/4),4^(1/4)]
 

In the above program , the equation eq was saved inside giac memory and remains there so when solve is called next, it can refer to it by name. Just like when using Giac interactively.

To obtain all 4 roots, need to use cSolve like this

#include <iostream> 
#include <fstream> 
#include <sstream> 
#include <string> 
 
 
#include <giac/config.h> 
#include <giac/giac.h> 
 
using namespace std; 
 
int main() 
{ 
 
    giac::context ct; 
 
    giac::eval( giac::gen("eq:=x^4-1=3",&ct) , 1, &ct); 
    giac::gen e = giac::eval( giac::gen("cSolve(eq,x)",&ct) , 1, &ct); 
 
    cout<<"The solution is " << e <<endl; 
 
    return 0; 
}

Compile and run

>make -I$HOME all 
>./main 
The solution is list[-sqrt(2),sqrt(2),-sqrt(2)*i,-sqrt(2)*(-i)]
 

4.4 example 3. C++ program to solve an ode

This program calls giac to solve \(y''+2 y'+y=0\) with ic \(y(0)=1,y'(0)=0\). Create this main.cc C++ file

#include <iostream> 
#include <fstream> 
#include <sstream> 
#include <string> 
 
 
#include <giac/config.h> 
#include <giac/giac.h> 
 
using namespace std; 
 
int main() 
{ 
 
    giac::context ct; 
    giac::gen e("desolve([diff(y(t),t$2)+2*diff(y(t),t)+y(t)=0,y(0)=1,y'(0)=0],y(t))",&ct); 
    e = giac::eval( e , 1, &ct); 
 
    cout<<"The solution to y''+2 y'+y=0 with ic  y(0)=1,y'(0)=0 is " << e <<endl; 
 
    return 0; 
}

Compile and run

>make -I$HOME all 
>./main 
The solution to y''+2 y'+y=0 with ic  y(0)=1,y'(0)=0 is exp(-t)*(t+1)