4
$\begingroup$

I recently stumbled upon a function F[X][Y] that has two separate arguments X,Y. Note that it is not of the form F[X, Y]!

So for F[X][Y], first F acts on X and then F[X] acts on Y. Now for the purposes of my work I need to split the function F = F1 + F2, but I can't successfully feed the second argument Y neither F1[X] nor F2[X] in the end.

Here's my description in code:

F[X][Y]
% /. F -> (F1[#] + F2[#] &)

this gives as an output

(F1[X] + F2[X])[Y]

but what I need as a desired output is

F1[X][Y] + F2[X][Y]

So my question is:

How can one start from F[X][Y] so that one ends up with the desired output F1[X][Y] + F2[X][Y]?

Bonus question.

Can the above happen by only changing the head of F?, i.e., modifying the rule /. F -> (F1[#] + F2[#] &) somehow?

$\endgroup$
  • 8
    $\begingroup$ % /. F -> (F1[#] + F2[#] &) // Through $\endgroup$ – Coolwater Feb 9 '19 at 14:24
  • 4
    $\begingroup$ % /. F[x_][y_] -> F1[x][y] + F2[x][y] $\endgroup$ – Roman Feb 9 '19 at 14:29
  • $\begingroup$ Thank you both a lot for your fast answers, both of them work perfectly. $\endgroup$ – Viktor Gakis Feb 9 '19 at 14:58
6
$\begingroup$

Just write it like any other function definition.

f[x_][y_] := f1[x][y] + f2[x][y]

Then

f[u][v]

gives

f1[u][v] + f2[u][v]
$\endgroup$
4
$\begingroup$

To address the 'Bonus question':

F[subFs_List, args__] := Total[Through[subFs[args]]] /. h_[x_, y__] /; MemberQ[subFs, h] :> h[x][y]

Evaluating F[{F1,F2},X,Y] returns

F1[X][Y]+F2[X][Y]

as expected


edit: The original answer above provided a solution in terms of F that doesn't work out-of-the-box, so to speak, when one already has an expression with terms involving F; in such a case, one can use ReplaceAll.

For the purposes of this amendment, consider an expression in F eg

expr = (a Log[F[X][Y]] - b /(c F[X][Y]) + d)^2 // Expand;

Then, expr /. F[X][Y] :> F[{F1, F2}, X, Y] returns, as expected:

d^2 + 2 a d Log[F1[X][Y] + F2[X][Y]] + a^2 Log[F1[X][Y] + F2[X][Y]]^2 
    + b^2/(c^2 (F1[X][Y] + F2[X][Y])^2) - (2 b d)/(c (F1[X][Y] 
    + F2[X][Y])) - (2 a b Log[F1[X][Y] + F2[X][Y]])/(c (F1[X][Y] + F2[X][Y]))

An alternative

In some cases, it might get confusing to have a transformation rule named after (having the same Head-sort of) the expression one is trying to transform; to tackle this problem, the transform can be conveniently renamed, as in

F /: expand[F[X][Y], subFs_: {F1, F2}] := 
  Total[Through[subFs[X, Y]]] /. h_[x_, y__] /; MemberQ[subFs, h] :> h[x][y]

This definition, attaches the transformation rule to F but avoids having F[X][Y] evaluate to anything in particular.

Here, it is assumed that F[X][Y] will be transformed using functions F1 and F2. This can be changed by supplying a different argument for subFs eg it could possibly be the case that instead of two, it takes three functions {F1, F2, F3} to factor F.

Now, evaluating expr /. patt : F[X][Y] :> expand[patt] should return the same expression as above, namely

d^2+2 a d Log[F1[X][Y]+F2[X][Y]]+a^2 Log[F1[X][Y]+F2[X][Y]]^2
    +b^2/(c^2 (F1[X][Y]+F2[X][Y])^2)-(2 b d)/(c (F1[X][Y]+F2[X][Y]))
    -(2 a b Log[F1[X][Y]+F2[X][Y]])/(c (F1[X][Y]+F2[X][Y]))
$\endgroup$
1
$\begingroup$
Through @ Operate[Apply[Plus @@ Through[{f1, f2} @ #] &], f[x][y]]

f1[x][y] + f2[x][y]

$\endgroup$
1
$\begingroup$

One way to achieve this is to realize that Plus[a,b][c] is actually not defined. So we can define it as we wish without changing much in the background mechanics of Mathematica.

With

Unprotect[Plus];
Plus[a_, b_][c_] := Plus[a[c], b[c]];
Protect[Plus];

we have what OP originally wanted:

(*In*)  F[X][Y]/.F->(F1[#]+F2[#]&)
(*Out*) F1[X][Y]+F2[X][Y]
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for?Browse other questions tagged or ask your own question.