Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Preventing expansion when multiplying expressions (Advice requested) #553

Open
jamievicary opened this issue Sep 10, 2024 · 1 comment
Open

Comments

@jamievicary
Copy link

Suppose I have J=A*x+A*y and K=B*x+B*y, where A, B are operators and x, y are scalars, and I want to compute P=J*K, and then apply the rewrite id A*B=C. I could do it in the most direct way like this:

NFunction A, B, C;
CF x, y;
Local J = A*x+A*y;
Local K = B*x+B*y;
Local P = J*K;
id A*B = C;
Print P;
.end

However this applies the rewrite 3 times, i.e. it performs the rewrite A*B*x^2+2*A*B*x*y+A*B*y^2 --> C*x^2+2*C*x*y+C*y^2. I would prefer to bracket J and K, to get J=A*(x+y) and K=B*(x+y), then multiply them to get J*K=A*B*(x^2+2*x*y+y^2), then apply the rewrite A*B=C just once to obtain the final result C*(x^2+2*x*y+y^2). I have attempted to do this using the Bracket command as follows:

NFunction A, B, C;
CF x, y;
Local J = A*x+A*y;
Local K = B*x+B*y;
Bracket A,B;
.sort
Keep Brackets;
Local P = J*K;
Print P;
id A*B = C;
Print P;
.end

My hope is that this does what I want. However I'm not too sure, since the final output is C*x^2+2*C*x*y+C*y^2, and not C*(x^2+2*x*y+y^2) as desired. However, it's possible it's applying the rewrite once and then expanding before printing, which would be OK (although I would prefer to be able to control the expansion.) Could anyone tell me what's going on?

It would be highly illuminating if I could count the number of times that a particular id rule is being applied; i.e. how many redexes were identified. Is it possible to extract this information?

@tueda
Copy link
Collaborator

tueda commented Sep 11, 2024

One of the basic principles of FORM is to always expand terms, which in turn splits the entire data into small chunks that are stored in localised memory regions and are beneficial for concurrency/parallelisation.

To avoid the expansion, one needs to put terms inside functions. Bracket + Collect is an option for that.

NF A,B,C;
CF x,y;

L J = A * x + A * y;
L K = B * x + B * y;
B A,B;
.sort

CF f;
Collect f,f,90;
.sort

Drop;
L P = J * K;
id A * B = C;
P;
.end
   P =
      C*f(x + y)^2;

To count the number of times that a particular rule is used, one can use a variant of "labeling each term uniquely". For example,

NF A,B,C;
S x,y;

L J = A * x + A * y;
L K = B * x + B * y;
B A,B;
.sort

CF counter;
Drop;
Keep Brackets;
L P = J * K;
#$counter = 1;
id ifnomatch->notfound, A * B = C * counter($counter);
$counter = $counter + 1;
label notfound;
P +s;
Moduleoption noparallel;
.end

gives

   P =
       + C*counter(1)*y^2
       + C*counter(2)*x*y
       + C*counter(3)*x*y
       + C*counter(4)*x^2
      ;

which shows that J * K is actually expanded (despite Keep Brackets) when substituted in the right-hand side of the definition of P.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants