# How to linearize function of functions?

From the post, I know how to linear a simple polynomial function of several independent variables.

For example, for two variables a1=q1+eps*q1 and a2=q2+eps*q2, the function f[a1_, a2_] = a1^2 a2 can be linearized by expanding in power series to first order with Series.

Now, I would like to linearize some functions of functions. For example, given a function F of two functions g[x] and h[x]:

F[g_, h_] = (1 - g[x]*h[x]*Log[g[x]/b])/(c*Log[g[x]/a] - d*Log[g[x]/b]);


For example, how do I linearize its first derivative and square?

dFdx[g_, h_] = D[F[g, h], x]; Fsquare[g_, h_] = F[g, h]^2;


The simple extension of the method in that link did not work.

(Series[dFdx[g0 + ϵ*dg, h0 + ϵ*dh], {ϵ, 0, 1}] // Normal) /. ϵ -> 1

(Series[Fsquare[g0 + ϵ*dg, h0 + ϵ*dh], {ϵ, 0, 1}] // Normal) /. ϵ -> 1


In the linearization, I need to eliminate any variable preceded by ϵ with power higher than 1 and any product of two variables preceded by ϵ. Thank you!

• Do not set \[Epsilon] -> 1. Instead, use Coefficient[%, \[Epsilon]]. Commented Feb 16, 2022 at 5:30
• I would define F as a function that also takes the independent variable x. That can make tasks like this easier. And it's also good practice in terms of coding. Commented Mar 18, 2022 at 15:02
• @DanielLichtblau, did you mean to define F[x_]=... or F[g_, h_, x_]=..., I'm just confused by that "also" in your comment. Thank you! Commented Mar 18, 2022 at 15:40
• By "also" I had in mind that latter, F[g_,h_,x_]:=.... Commented Mar 18, 2022 at 21:43

modified

Assuming g[x]-g0[x], h[x]-h0[x]to be small of equal order try

Fx = D[F[g, h],x] /. {g -> (g0[#] + eps dg[#] &), h -> (h0[#] + eps dh[#] &)}
Normal[Series[Fx, {eps, 0, 1}]] /. eps -> 1 /. { dg[x] -> g[x] - g0[x],dh[x] -> h[x] - h0[x]} // Simplify
(* lengthy output...*)

F2 = F[g, h]^2 /. {g -> (g0[#] + eps dg[#] &), h -> (h0[#] + eps dh[#] &)}
Normal[Series[F2, {eps, 0, 1}]] /. eps -> 1 /. { dg[x] -> g[x] - g0[x], dh[x] -> h[x] - h0[x]} // Simplify

(* (1/((c Log[g0[x]/a] - d Log[g0[x]/b])^3))(-((
2 (c - d) (g[x] - g0[x]) (-1 + g0[x] h0[x] Log[g0[x]/b])^2)/
g0[x]) + (c Log[g0[x]/a] - d Log[g0[x]/b]) (-1 +g0[x] h0[x]Log[g0[x]/b])^2 +
2 (c Log[g0[x]/a] - d Log[g0[x]/b]) (1 - g0[x] h0[x] Log[g0[x]/b]) (-((g[x] - g0[x]) h0[x]) - (g0[x] (h[x] - 2 h0[x]) + g[x] h0[x]) Log[g0[x]/b]))*)


Hope it's what you are looking for!

I think you're confusing the terms "function" and "expression," which I used to struggle with. In strict, pedantic math, a function $$f$$ can be applied to an argument like $$f(a)$$ or $$f(3)$$; and an expression like $$x^2$$ cannot: $$x^2(a)$$ and $$x^2(3)$$ do not mean $$a^2$$ or $$3^2$$. It does not help that in colloquial math, we say $$x^2$$ is a function and know what it means to evaluate it at $$3$$. Basic common sense and experience tell us that $$x^2(3)$$ is nonsense and not what the speaker meant and that they must mean to substitute $$x=3$$ into the expression $$x^2$$.

Likewise in Mathematica, there are two notions, function and expression, similar to the mathematical concepts. If an argument to F[g_, h_] is g = g0+ε*dg, then g[x] is (g0+ε*dg)[x], which is nonsense, albeit syntactically correct nonsense. That it is syntactically acceptable to Mathematica does not imply there is any built-in meaning to it. In the g[x] usage here, g is an expression being (mis)treated as a function.

One other thing before we get started. To linearize the derivative of a function requires the quadratic terms of the series expansion of the function. This is different from taking the derivative of the linearization. I assume the first is meant.

The first order of business then is to sort out whether you want F[] to operate on functions g, h or on expressions g, h. Since the linked post operates on expressions, then let's do that. As @DanielLichtblau said in the comments, it's best in this case to identify the independent variable that the expressions are functions of.

An "expressional" approach:

(* Better to use SetDelayed (:=) instead of Set (=)
unless there is a specific reason not to.        *)
F // ClearAll;
F[g_, h_] := (1 - g*h*Log[g/b])/(c*Log[g/a] - d*Log[g/b]);

dFdx // ClearAll;
dFdx[g_, h_, x_] := D[F[g, h], x];
Fsquare // ClearAll;
Fsquare[g_, h_] := F[g, h]^2;

s1 = (Series[dFdx[
g0 + ε*dg + ε^2/2*d2g,
h0 + ε*dh + ε^2/2*d2h, ε], {ε, 0, 1}] //
Normal) /. ε -> 1
s2 = (Series[Fsquare[g0 + ε*dg, h0 + ε*dh], {ε, 0, 1}] //
Normal) /. ε -> 1


They have rather complicated output. If one wants to check the coefficients, then one could use CoefficientList[lin, {dg, dh}] or Coefficient[lin, dg] etc., where lin is one of the outputs.

A functional approach:

Here's a function-based approach in case that is desired or of interest. We can redefine things as follows:

F // ClearAll;
F[g_, h_] =  Function[ x,
(1 - g[x]*h[x]*Log[g[x]/b])/(c*Log[g[x]/a] - d*Log[g[x]/b])];

dFdx // ClearAll;
dFdx[g_, h_] = F[g, h]';
Fsquare // ClearAll;
Fsquare[g_, h_] = Function[x, F[g, h][x]^2];

sub = {g[x0] -> g0, g'[x0] -> dg, g''[x0] -> d2g,
h[x0] -> h0, h'[x0] -> dh, h''[x0] -> d2h};
ss1 = (Series[dFdx[g, h][x0 + ε, {ε, 0, 1}] //
Normal) /. ε -> 1 /. sub
ss2 = (Series[Fsquare[g, h][x0 + ε], {ε, 0, 1}] //
Normal) /. ε -> 1 /. sub


Check both approaches give the same output:

s1 == ss1 // Simplify
s2 == ss2 // Simplify
(*
True
True
*)


To expand F around x==x0 you would write:

F[g_, h_] = (1 - g[x]*h[x]*Log[g[x]/b])/(c*Log[g[x]/a] -
d*Log[g[x]/b]);
Series[F[g, h], {x, x0, 1}] // Normal
`

• thanks! it is the expansion of F, but how do I linearize its first derivative and square? Commented Mar 12, 2022 at 3:32
• Simple, instead of F in the expansion, you use F'. And for the square, you use F[..]^2 Commented Mar 15, 2022 at 15:52