How to linearize an expression automatically?

7

3

I would like to automatically linearize some long equations in the scope of variational calculus. Here follows an example of what I need to do :

Given two variables $a_1 = q_1 + \delta q_1$ and $a_2 = q_2 + \delta q_2$ and a product $${a_1}^2\, a_2 = {q_1}^2 q_2 + 2q_1q_2\delta q_1 + q_2{\delta q_1}^2 + {q_1}^2\delta q_2 + 2q_1\delta q_1 \delta q_2 + {\delta q_1}^2 \delta q_2$$

I would like to eliminate any variable preceded by the $\delta$ symbol which power is superior to 1 (make it equal to zero), and any product of two variables preceded by the $\delta$ symbol (make the product equal to zero also). So as to obtain :

$${a_1}^2\, a_2 = {q_1}^2 q_2 + 2q_1q_2\delta q_1 + {q_1}^2\delta q_2$$

I first tried the Assumptions options while expanding :

a1 = Subscript[q, 1] + Subscript[\[Delta]q, 1];
a2 = Subscript[q, 2] + Subscript[\[Delta]q, 2];
Expand[a1^2*a2, Assumptions -> Subscript[\[Delta]q, 1]^2 = 0]

Which returned the following :

Set::write: Tag Rule in Assumptions->Subsuperscript[\[Delta]q, 1, 2] is Protected. >>
(Subscript[q, 1] + Subscript[\[Delta]q, 1])^2 (Subscript[q, 
   2] + Subscript[\[Delta]q, 2])

Of course it didn't work. Truth is that I don't know how to start this... Does someone has any ideas?

I also tried :

a1 = Subscript[q, 1] + Subscript[\[Delta]q, 1];
a2 = Subscript[q, 2] + Subscript[\[Delta]q, 2];
b = Expand[a1^2*a2];
Assuming[Subscript[\[Delta]q, 1]^2 == 0, b]

which didn't work either and returned :

\!\(
\*SubsuperscriptBox[\(q\), \(1\), \(2\)]\ 
\*SubscriptBox[\(q\), \(2\)]\) + 
 2 Subscript[q, 1] Subscript[q, 2] Subscript[\[Delta]q, 1] + 
 Subscript[q, 2] 
\!\(\*SubsuperscriptBox[\(\[Delta]q\), \(1\), \(2\)]\) + \!\(
\*SubsuperscriptBox[\(q\), \(1\), \(2\)]\ 
\*SubscriptBox[\(\[Delta]q\), \(2\)]\) + 
 2 Subscript[q, 1] Subscript[\[Delta]q, 1] Subscript[\[Delta]q, 
  2] + \!\(
\*SubsuperscriptBox[\(\[Delta]q\), \(1\), \(2\)]\ 
\*SubscriptBox[\(\[Delta]q\), \(2\)]\)

Meclassic

Posted 2013-06-03T13:48:55.067

Reputation: 683

As noted by Mathematica, you used Set[] (=) where you should have used Equal[] (==). Mind the difference! – J. M.'s ennui – 2013-06-03T13:51:53.797

Well, Expand[] is not at all affected by Assuming[], notwithstanding the fact that you did the expansion outside the confines of Assuming[]. Try Assuming[Subscript[δq, 1] == 0, Simplify[a1^2 a2] // Expand]. – J. M.'s ennui – 2013-06-03T14:10:38.503

@J. M. I don't want to neglect every term with Subscript[δq, 1], but only if its exponent is >1 or if its multiplied by another δ term... I tried Assuming[Subscript[δq, 1]^2 == 0, Simplify[a1^2 a2] // Expand], but still doesn't work – Meclassic – 2013-06-03T14:57:26.317

Answers

12

I'd use Series :

f[a1_, a2_] = a1^2 a2;

(Series[f[q1 + \[Epsilon] dq1, q2 + \[Epsilon] dq2], {\[Epsilon], 0, 1}] // Normal) 
  /. \[Epsilon] -> 1
(* dq2 q1^2 + 2 dq1 q1 q2 + q1^2 q2 *)

b.gates.you.know.what

Posted 2013-06-03T13:48:55.067

Reputation: 18 845

1

I encountered the same question. My approach is to take partial derivatives w.r.t. all variables to be linearized to construct the linearized expression, plus the constant term:

(* Expression to be linearized in da, db, dc *)
expr = da*db + da^2 + db^3 + dc + da*dc^2 + 12
(* Make List of all vars to be linearized *)
ds = {da, db, dc};
(* Create list of rules *)
rules = Table[ds[[i]] -> 0, {i, 1, 3}];
(* Construct linearized expression by using first derivatives and rules *)
linexpr = Sum[(D[expr, ds[[i]]] /. rules) ds[[i]], {i, 1, 3}] + (expr /. rules)

The output is

12 + da^2 + da db + db^3 + dc + da dc^2
12 + dc

Hope this helps.

Rainer Glüge

Posted 2013-06-03T13:48:55.067

Reputation: 461