# Algebraic manipulation in Root

I’m writing some code that involves symbolic manipulation of 2x2 matrices of 3rd order bi-polynomials (which are fitted from 2D TProfiles). I’ve made a class to do most of this, which basically consists of a 2x2 array of TF2 objects and various methods to add, multiply, and invert these functional matrices. The problem is that TFormula inserts many of its own parentheses into algebraic expressions so it only has to interpret binary operations (e.g., it changes “x + y + 1” into “((x + y) + 1)”), and given the size of the polynomials I’m using, TFormula quickly becomes overloaded with operators and Root crashes.

`` It would be nice to find a way to implement Mathematica or some other software with better symbolic algebra capabilities through Root, although I don't know specifically how to go about doing this.  Does anyone have any suggestions?``

Michael,

Could you send an example of a TF2 crashing ?

Note that we have an interface with mathematica. see
root.cern.ch/root/HowtoMathematica.html

Rene

Thank you for your reply. gTybalt looks like a potential solution, although I will have to spend some more time reading about it.

`````` Well, the operation that I believe overloaded TFormula was when I ran my invert function on my TF2 matrix class.  The function basically multiplies the functions (using their names), viz.:
``````
``````Char_t buf[256];

snprintf(buf, sizeof(buf), "%s*%s - %s*%s", x[0][0]->GetName(), x[1][1]->GetName(), x[0][1]->GetName(), x[1][0]->GetName());
TF2* det = new TF2(MakeName(), buf, x_min, x_max, y_min, y_max);

snprintf(buf, sizeof(buf), "(%s)/(%s)", x[1][1]->GetName(), det->GetName());
x[0][0] = new TF2(MakeName(), buf, x_min, x_max, y_min, y_max);

snprintf(buf, sizeof(buf), "((-1)*%s)/(%s)", x[0][1]->GetName(), det->GetName());
x[0][1] = new TF2(MakeName(), buf, x_min, x_max, y_min, y_max);

snprintf(buf, sizeof(buf), "((-1)*%s)/(%s)", x[1][0]->GetName(), det->GetName());
x[1][0] = new TF2(MakeName(), buf, x_min, x_max, y_min, y_max);

snprintf(buf, sizeof(buf), "(%s)/(%s)", x[0][0]->GetName(), det->GetName());
x[1][1] = new TF2(MakeName(), buf, x_min, x_max, y_min, y_max);``````

where x[i][j] are the names of TF2 matrix members. Again, since these functions are all long polynomials, I’m assuming the number of parentheses just becomes unmanageable.

Michael,

It would be good if you could provide a running script that I can execute to test this problem. Could you also specify which version of ROOT you are using?

Rene

I’m using version 5.14.

Attached is the class MFunction which I created to handle the function matrices. Currently the MFunction::Invert doesn’t work properly anyway, although it is the method that apparently create too many operators for TFormula.

I suppose in general it would just be nice to have some sort of simplification mechanisms for algebraic expressions, e.g., simplifying “0*(x^2 + 2*y - 1)” to “0.” Based on the little I know about it, gTybalt might be able to remedy this, although I don’t know for sure.

I did look into the Mathematica implementation in Root a while ago, although it seemed that was to use Mathematica’s numerical functions (such as Gamma) as opposed to its algebra system.
MProfile.h (639 Bytes)
MFunction.C (4.82 KB)

You forgot to send MFunction.h and a small script showing the problem.

Rene

Whoops – ignore the MProfile code. Here is the MFunction header file and a Root macro using the faulty MFunction::Invert method. Currently I haven’t been able to reproduce the TFormula “too many operators” error, but as this macro shows, too many of these symbolic calculations could quickly get out of hand and conceivably lead to such an error. Please also let me know if you happen to have any suggestions for fixing the inversion code.
TestMFunction.C (1.36 KB)
MFunction.h (1006 Bytes)

Well, with some help I’ve managed to repair the MFunction::Invert method (and the similarly problematic MFunction::Multiply) using some temporary TF2s. I also experienced another crash from TFormula which seemed to follow from running, in sequence, MFunction::MakeDiagonal, MFunction::AverageDiagonals, and MFunction::InvertFast on a matrix of 3rd order bi-polynomials, although I’ve been able to do this successfully in isolated tests.

TFormula/TF1 has no problem with your function having only a few tens of operations or constants. However we had a limitation to a maximum of 1000 operations, parameters or constants. I have added a new static function TFormula::SetMaxima to increase/decrease the default value for these maxima. see:
root.cern.ch/root/html/TFormula. … :SetMaxima

When looking at your code, I see a potentially dangerous and innefficient contruct in your function MFunction::Eval. Instead of returning a TMatrixD, I suggest to specify a TMatrixD by reference as argument to this function. See your modified functions in attachment.

Rene
TestMFunction.C (1.59 KB)
MFunction.C (4.83 KB)
MFunction.h (1010 Bytes)