vermaseren / form

The FORM project for symbolic manipulation of very big expressions
GNU General Public License v3.0
982 stars 118 forks source link

Access contents of brackets #373

Closed LorenzoTancredi closed 1 year ago

LorenzoTancredi commented 3 years ago

Hi everyone,

i have a question about the bracket statement. Assume I have an expression which is a polynomial in many variables, say x1,...,xn, where n could be very large, and that the coefficients are complicated combinations of other objects, which I'll call f(j...), so my expressions is a sum of monomials of this type

x1^j1x2^j2...xn^jnf(j1,...,jn)

To be clear, f is just a placeholder, ie f(j1,...,jn) could be itself a polynomial in other variables unrelated to the xj ec.

Now I'd like to access, as fast as possible, a list of all the f(j1,...,jn), without having to know a priori what the j1,...,jn are.

In mathematica I would do a collect and a Cases statement.

Now in form, If I knew the js, I could do I guess something like

b x1,...,xn ; .sort l tmp = expr[x1^j1...xn^jn] ;

but I don't want to have to figure out the jns a priori, as this information should be inside form already when I do "bracket". I could also use dollar variables to read the content of the brackets, doing something like

b x1,...,xn ; .sort collect fun ; .sort

and then use dollar variables to read all possible arguments of the functions "fun", but this is extremely slow for long expressions.

I imagine that, since form has internally the information about the brackets, there has to be a way to access them somewhere without doing something this convoluted? Or am I missing something obvious? I am thinking of something like activeexprnames_ but for the brackets...

maybe there is even a different/simpler solution that I don't see?

Thank you everyone for your help! Lorenzo

vermaseren commented 3 years ago

Hi Lorenzo,

If I understand you correctly, the statement for you is the antibracket statement. If you use: AntiBracket x1,…,xn; .sort KeepBrackets;

you will work on the f and each different f occurs only once. Only at the end of the module the contents of the brackets will be multiplied by whatever you made of the f’s.

You can start inpsecting what you have you could start with AB x1,…,xn; Print[]; .end

which will show a list of all different f’s and how many terms there are inside each bracket.

I hope this is what you are after.

Cheers

Jos

On 20 Jan 2021, at 10:55, LorenzoTancredi notifications@github.com wrote:

Hi everyone,

i have a question about the bracket statement. Assume I have an expression which is a polynomial in many variables, say x1,...,xn, where n could be very large, and that the coefficients are complicated combinations of other objects, which I'll call f(j...), so my expressions is a sum of monomials of this type

x1^j1x2^j2...xn^jnf(j1,...,jn)

To be clear, f is just a placeholder, ie f(j1,...,jn) could be itself a polynomial in other variables unrelated to the xj ec.

Now I'd like to access, as fast as possible, a list of all the f(j1,...,jn), without having to know a priori what the j1,...,jn are.

In mathematica I would do a collect and a Cases statement.

Now in form, If I knew the js, I could do I guess something like

b x1,...,xn ; .sort l tmp = expr[x1^j1...xn^jn] ;

but I don't want to have to figure out the jns a priori, as this information should be inside form already when I do "bracket". I could also use dollar variables to read the content of the brackets, doing something like

b x1,...,xn ; .sort collect fun ; .sort

and then use dollar variables to read all possible arguments of the functions "fun", but this is extremely slow for long expressions.

I imagine that, since form has internally the information about the brackets, there has to be a way to access them somewhere without doing something this convoluted? Or am I missing something obvious? I am thinking of something like activeexprnames_ but for the brackets...

maybe there is even a different/simpler solution that I don't see?

Thank you everyone for your help! Lorenzo

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/vermaseren/form/issues/373, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABJPCESGYA7YMPMBBAIGAHLS22SA5ANCNFSM4WKNA2LQ.

LorenzoTancredi commented 3 years ago

Hi Jos,

thank you for your quick answer.

Well I would like to have access to them, say be able to have their names, so to be able to write them on a file for example...

Let's make an explicit example. Suppose that the problem I want to solve is something like finding a linear combinations of some objects that is zero. So suppose I have N objects y1,...,yN and I know that each yj is a polynomial in x1,...,xn.

I want to solve the problem

a1y1 + ... + aNyN = 0, with aj rational numbers

what I would do is write every yj as polynomials in xj, then do

b x1,...,xn ; .sort collect f ; .sort

now I want the list of all these f(...), which are linear in the aj, which I will want to put to zero.

Maybe there is a simpler way to go about this? Usually I do this with dollar variables, but it seems super inefficient...

Best, Lorenzo

jodavies commented 3 years ago

As far as I know, the last part of the section about #do https://www.nikhef.nl/~form/maindir/documentation/reference/online/online.html#SECTION004190000000000000000 is the only way to iterate over the outside of (anti)brackets which avoids the use of dollar variables (which might become too large).

LorenzoTancredi commented 3 years ago

Oh that's wonderful, indeed... I think that's exact what I need. Thanks Joshua! Hope all is fine for you in these crazy times :)

vermaseren commented 3 years ago

Hi Lorenzo,

Cannot you work with tables? Say you have N variables and your expression is called F.. Define Table,sparse,zerofill,XX(N’); B x1,…,xN’; .sort FillExpression XX = F(x1,…,xN’); .sort Drop F; Now all the objects that you had before in your collect are instead in a table. That is much faster. You can now access them with nested #do’s. If there are too many for that you could insert somewhere before you drop F something like id x2 = x1; … id xN’ = x1; and then get the maximum combined power which can put an upperlimit on the #do’s that is more realistic. Of course, if `N’ is very large and that sum power is also large that may not work very well. The advantage of the table is that it will give zero very quickly when an element does not exist. Hence if you have

do j1 = 1,…

do j2 = 1,…

L tmp = XX(j1’,j2’); .sort

if (termsin(tmp) != 0 )

 code

endif

enddo

enddo

does not give much overhead. As sais, all if the nesting of the #do’s is not a disaster.

Cheers

Jos

On 20 Jan 2021, at 11:32, LorenzoTancredi notifications@github.com wrote:

Hi Jos,

thank you for your quick answer.

Well I would like to have access to them, say be able to have their names, so to be able to write them on a file for example...

Let's make an explicit example. Suppose that the problem I want to solve is something like finding a linear combinations of some objects that is zero. So suppose I have N objects y1,...,yN and I know that each yj is a polynomial in x1,...,xn.

I want to solve the problem

a1y1 + ... + aNyN = 0, with aj rational numbers

what I would do is write every yj as polynomials in xj, then do

b x1,...,xn ; .sort collect f ; .sort

now I want the list of all these f(...), which are linear in the aj, which I will want to put to zero.

Maybe there is a simpler way to go about this? Usually I do this with dollar variables, but it seems super inefficient...

Best, Lorenzo

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/vermaseren/form/issues/373#issuecomment-763506798, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABJPCESOIRUKU3MP2ZYF3F3S22WLDANCNFSM4WKNA2LQ.

vermaseren commented 3 years ago

It does not loop over the brackets, but over the terms. Hence you would need to do a collect first, but then it does work, provided the antibrackets are not too large. One can however set the collect(…) equal to one to just get a list of all the brackets. In that case it works and one can pick up the proper brackets afterwards.

On 20 Jan 2021, at 11:44, jodavies notifications@github.com wrote:

As far as I know, the last part of the section about #do https://www.nikhef.nl/~form/maindir/documentation/reference/online/online.html#SECTION004190000000000000000 https://www.nikhef.nl/~form/maindir/documentation/reference/online/online.html#SECTION004190000000000000000 is the only way to iterate over the outside of (anti)brackets which avoids the use of dollar variables (which might become too large).

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/vermaseren/form/issues/373#issuecomment-763513908, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABJPCEUXU6UDHVMRGWSOCN3S22XX3ANCNFSM4WKNA2LQ.

LorenzoTancredi commented 3 years ago

Thank you guys, that works nicely!

Lorenzo

benruijl commented 1 year ago

A solution using extrasymbols is provided in the cookbook.