# [Applied Algebra] a method for calculating a large number of polynomials with c + + symbols (compilation error when the symbol table is too large)

## A method for computing a large number of polynomials with c + + symbols (compilation error when the symbol table is too large)

When using the C + + symbolic computation library GiNaC for symbolic computation, because there are too many polynomials to be processed and they are defined in the. cpp/.h file, g + + compilation always fails after running for a long time; We conceive a method of reading text from the outside and parsing it into corresponding symbols to solve this problem;

### Problem description

When using the C + + symbolic calculation library GiNaC for symbolic calculation, because there are too many polynomials to be processed, they are defined in the. cpp/.h file:

```std::vector<GiNaC::ex> ITEMS_ZTT {t1*z664, t2*z664,...}; // There are more than 2000 monomials;
std::vector<GiNaC::ex> EQUATIONS_420 {t39*z979 + t40*z979 + z749...,...}; // This has more than 2000 polynomials;
```

When compiling, an error will be reported due to insufficient memory (the symbol table is too large):

```[hanss@Tenda cpp]\$ g++ app_gauss.cpp -o app -lginac -lcln
g++: internal compiler error: Segmentation fault (program cc1plus)
Please submit a full bug report,
with preprocessed source if appropriate.
```

### resolvent

A direct idea is that since there are too many symbols defined in the operation of "write formula", can it be defined at runtime instead of at compile time?

How can C + + dynamically declare a variable with a string?

In fact, no; Because the symbol table is generated at the beginning of program creation;
So the compromise idea is: I only create basic symbols, such as arguments:

```GiNaC::symbol x1("x1"), x2("x2"), x3("x3"), x4("x4"), x5("x5"), x6("x6"), x7("x7"), x8("x8"), x9("x9");
```

Then store the formula to be calculated in the static. dat file, and then just read it and analyze it:

```z1*c1 + z2*c2 + z3*c3 + z4*c4 + z5*c5 + z6*c6 + z7 + z8
z1*c2 + z3*c4 + z1 + z3
...
```

Therefore, the required functions include file reading / symbol analysis / formula generation. The whole program is as follows:

```#include <vector>
#include <string>
#include <iostream>
#include <cstring>
#include <fstream>
#include <ginac/ginac.h>
#include <map>
// g++ formula_resolution.cpp -o hello -lginac -lcln
#define MAX_LEN_LINE 200

using namespace std;

{
char THIS_LINE[MAX_LEN_LINE];
string FORMULA_STRING;
string TMP_VAR;
std::ifstream FILEIN(FILE_NAME);
std::vector<string> FORMULA_STRING_SET;
for (;;)
{
FILEIN.getline( THIS_LINE, sizeof(THIS_LINE));
if ( FILEIN.eof()){break;}
std::vector<int> COEFF;
for (int j = 0; j < MAX_LEN_LINE; ++j)
{
if ( THIS_LINE[j]=='\0'){break;}
TMP_VAR = THIS_LINE[j];
FORMULA_STRING += TMP_VAR;
}
FORMULA_STRING_SET.push_back(FORMULA_STRING);
FORMULA_STRING.clear();
}
FILEIN.close();
return FORMULA_STRING_SET;
}

vector<string> split(const string& PROCESS_STRING, const string& DELIM) {
vector<string> res;
if("" == PROCESS_STRING) return res;
char * strs = new char[PROCESS_STRING.length() + 1] ;
strcpy(strs, PROCESS_STRING.c_str());

char * d = new char[DELIM.length() + 1];
strcpy(d, DELIM.c_str());

char *p = strtok(strs, d);
while(p) {
string s = p;
res.push_back(s);
p = strtok(NULL, d);
}

return res;
}

GiNaC::ex make_poly_from_string(const string& PROCESS_STRING,std::map<string,GiNaC::symbol> MAP_STR_SYMBOL)
{
std::vector<string> STR_MONOMIALS = split(PROCESS_STRING, " + ");
GiNaC::ex POLYNOMIAL = 0;
for (int INDEX_i = 0; INDEX_i < STR_MONOMIALS.size(); ++INDEX_i)
{
std::vector<string> STR_SYMBOLS = split(STR_MONOMIALS[INDEX_i], "*");
if (STR_SYMBOLS.size()==1)
{
POLYNOMIAL+=MAP_STR_SYMBOL[STR_SYMBOLS ];
continue;
}
GiNaC::ex MONOMIAL = 1;
for (int INDEX_j = 0; INDEX_j < STR_SYMBOLS.size(); ++INDEX_j)
{
MONOMIAL *= MAP_STR_SYMBOL[STR_SYMBOLS[INDEX_j] ];
}
POLYNOMIAL += MONOMIAL;
}
return POLYNOMIAL;
}

std::map<string,GiNaC::symbol> construct_map(const std::vector<GiNaC::symbol>& ITEMS_X)
{
std::map<string,GiNaC::symbol> MAP_STR_SYMBOL;
for (int INDEX_i = 0; INDEX_i < ITEMS_X.size(); ++INDEX_i)
{
MAP_STR_SYMBOL[ITEMS_X[INDEX_i].get_name()] = ITEMS_X[INDEX_i];
}
return MAP_STR_SYMBOL;
}

std::vector<GiNaC::ex> ppsh_read_formulas_from_file(const string& FILE_NAME, std::map<string,GiNaC::symbol> MAP_STR_SYMBOL)
{
std::vector<GiNaC::ex> EQUATIONS_192;
for (int INDEX_i = 0; INDEX_i < FORMULA_STRING_SET.size(); ++INDEX_i)
{
EQUATIONS_192.push_back(make_poly_from_string(FORMULA_STRING_SET[INDEX_i],MAP_STR_SYMBOL));
}
return EQUATIONS_192;
}

int main()
{
GiNaC::symbol x1("x1"), x2("x2"), x3("x3"), x4("x4"), x5("x5"), x6("x6"), x7("x7"), x8("x8"), x9("x9");
std::vector<GiNaC::symbol> ITEMS_X {x1, x2, x3, x4, x5, x6, x7, x8, x9};
std::map<string,GiNaC::symbol> MAP_STR_SYMBOL = construct_map(ITEMS_X);
for (int i = 0; i < EQUATIONS_192.size(); ++i)
{
cout << EQUATIONS_192[i] <<endl;
}
}
```

For the whole project, we can refer to the symbolic calculation program of polynomials over finite fields written by our group:

```https://github.com/Luomin1993/PPSH-41
```

### Another small problem: how to compile the source code and reference it on a server without root permission

On a server without root permission, you need to compile a library (CLN) and a library GiNac that depends on CLN. Finally, you need to compile your GiNac dependent c + + program with g + +. All these can be done as follows:

```[hanss@Tenda cpp]\$ ./configure --prefix=\$HOME/usr // Before compiling CLN
[hanss@Tenda cpp]\$ make // Compile CLN
[hanss@Tenda cpp]\$ make install // Install CLN
[hanss@Tenda cpp]\$ export PKG_CONFIG_PATH=\$HOME/usr/lib/pkgconfig // Indicates the CLN library
[hanss@Tenda cpp]\$ ./configure --prefix=\$HOME/usr // Before compiling GiNaC
[hanss@Tenda cpp]\$ make // Compile GiNaC
[hanss@Tenda cpp]\$ make install // Install GiNaC
[hanss@Tenda cpp]\$ g++ hello.cc -o hello -I\$HOME/usr/include -L\$HOME/usr/lib -lginac -lcln // Compile your program
[hanss@Tenda cpp]\$ export LD_LIBRARY_PATH=\$HOME/usr/lib // Before running the program
[hanss@Tenda cpp]\$ ./hello // Run program
```

Tags: C++

Posted on Sun, 10 Oct 2021 08:52:18 -0400 by peteraub