next up previous contents index
Next: Vector Differentiation Up: Examples Previous: Examples   Contents   Index

Simplifying a Complicated Expression

The next example is one most people would be advised to work through.

Note that the output of In[2] below will change based upon which version of NCAlgebra you have. We have not changed this output each time we have a new release. If the example does not work in any way, let us know.

In[2]:= <<NCAlgebra.m

You see a long list of files which NCAlgebra.m is loading 
scroll by on the screen.
There may be a few changes to what is documented above.

In[3]:= <<NCMessyFunction.m
NCMessyFunction.m contains several grubby functions. The variable coexz was defined in the file NCMessyFunction.m. Also, a lot of variables are defined to be noncommutative in that file. As an exercise let us simplify the expression named coexz.
In[5]:= coexz

Out[5]= -tp[C1] ** C1 - XX ** B2 ** inv[d12] ** C1 - 
   tp[C1] ** inv[tp[d12]] ** tp[B2] ** XX - 
   XX ** inv[1 - YY ** XX] ** B1 ** inv[d21] ** C2 - 
   XX ** inv[1 - YY ** XX] ** B1 ** tp[B1] ** XX + 
   inv[YY] ** inv[1 - YY ** XX] ** B1 ** inv[d21] ** C2 + 
   inv[YY] ** inv[1 - YY ** XX] ** B1 ** tp[B1] ** XX - 
   XX ** B2 ** inv[d12] ** inv[tp[d12]] ** tp[B2] ** XX - 
   XX ** inv[1 - YY ** XX] ** YY ** tp[C2] ** 
   inv[tp[d21]] ** inv[d21] ** C2 - 
   XX ** inv[1 - YY ** XX] ** YY ** tp[C2] ** 
   inv[tp[d21]] ** tp[B1] ** XX + 
   inv[YY] ** inv[1 - YY ** XX] ** YY ** tp[C2] ** inv[tp[d21]] ** 
   inv[d21] ** C2 + inv[YY] ** inv[1 - YY ** XX] ** YY ** tp[C2] ** 
   inv[tp[d21]] ** tp[B1] ** XX

In[6]:= NCForward[ coexz ]
applies the basic rule

$\displaystyle XX**inv[1-YY**XX] \rightarrow inv[1-XX**YY]**YY
$

Out[6]= -tp[C1] ** C1 - XX ** B2 ** inv[d12] ** C1 - 
   tp[C1] ** inv[tp[d12]] ** tp[B2] ** XX - 
   inv[1 - XX ** YY] ** XX ** B1 ** inv[d21] ** C2 - 
   inv[1 - XX ** YY] ** XX ** B1 ** tp[B1] ** XX + 
   inv[1 - XX ** YY] ** inv[YY] ** B1 ** inv[d21] ** C2 + 
   inv[1 - XX ** YY] ** inv[YY] ** B1 ** tp[B1] ** XX + 
   inv[1 - XX ** YY] ** tp[C2] ** inv[tp[d21]] ** inv[d21] ** C2 + 
   inv[1 - XX ** YY] ** tp[C2] ** inv[tp[d21]] ** tp[B1] ** XX - 
   XX ** B2 ** inv[d12] ** inv[tp[d12]] ** tp[B2] ** XX - 
   inv[1 - XX ** YY] ** XX ** YY ** tp[C2] ** inv[tp[d21]] ** 
   inv[d21] ** C2 - inv[1 - XX ** YY] ** XX ** YY ** tp[C2] ** 
   inv[tp[d21]] ** tp[B1] ** XX

In[7]:= NCCollect[ %, B1 ** inv[d21] ** C2 ] 
Taylor expansion of 6 in the variable $ B1 ** inv[d21] ** C2$.
 
TermApplyRules has to loop 1 times. Please be patient.
Finished iteration number 1

Out[7]= -tp[C1] ** C1 - XX ** B2 ** inv[d12] ** C1 - 
   (inv[1 - XX ** YY] ** XX - inv[1 - XX ** YY] ** inv[YY]) ** B1 ** 
   inv[d21] ** C2 - tp[C1] ** inv[tp[d12]] ** tp[B2] ** XX - 
   inv[1 - XX ** YY] ** XX ** B1 ** tp[B1] ** XX + 
   inv[1 - XX ** YY] ** inv[YY] ** B1 ** tp[B1] ** XX + 
   inv[1 - XX ** YY] ** tp[C2] ** inv[tp[d21]] ** inv[d21] ** C2 + 
   inv[1 - XX ** YY] ** tp[C2] ** inv[tp[d21]] ** tp[B1] ** XX - 
   XX ** B2 ** inv[d12] ** inv[tp[d12]] ** tp[B2] ** XX - 
   inv[1 - XX ** YY] ** XX ** YY ** tp[C2] ** 
   inv[tp[d21]] ** inv[d21] ** C2 - 
   inv[1 - XX ** YY] ** XX ** YY ** tp[C2] ** inv[tp[d21]] ** 
   tp[B1] ** XX

In[8]:= NCC[ %, B1 ** tp[B1] ** XX ]
NCC is an alias for NCCollect.
 
TermApplyRules has to loop 1 times. Please be patient.
Finished iteration number 1

Out[8]= -tp[C1] ** C1 - XX ** B2 ** inv[d12] ** C1 - 
   (inv[1 - XX ** YY] ** XX - inv[1 - XX ** YY] ** inv[YY]) ** B1 ** 
   inv[d21] ** C2 - (inv[1 - XX ** YY] ** XX - 
   inv[1 - XX ** YY] ** inv[YY]) ** B1 ** tp[B1] ** XX - 
   tp[C1] ** inv[tp[d12]] ** tp[B2] ** XX + 
   inv[1 - XX ** YY] ** tp[C2] ** inv[tp[d21]] ** inv[d21] ** C2 + 
   inv[1 - XX ** YY] ** tp[C2] ** inv[tp[d21]] ** tp[B1] ** XX - 
   XX ** B2 ** inv[d12] ** inv[tp[d12]] ** tp[B2] ** XX - 
   inv[1 - XX ** YY] ** XX ** YY ** tp[C2] ** inv[tp[d21]] ** 
   inv[d21] ** C2 - inv[1 - XX ** YY] ** XX ** YY ** tp[C2] ** 
   inv[tp[d21]] ** tp[B1] ** XX

In[9]:= Substitute[%, inv[1-XX**YY]**XX - inv[1-XX**YY]**inv[YY] -> -inv[YY]] 
Here we are using an approach that favors collecting pairs of terms that have similar leftmost inv[1-XX**YY]'s and rightmost non-inv[1-XX**YY] parts. And now, we are substituting the identity:

$\displaystyle inv[1-a**b]**b - inv[1-a**b]**inv[b] == -inv[b]
$

 

Out[9]= -tp[C1] ** C1 - XX ** B2 ** inv[d12] ** C1 + 
   inv[YY] ** B1 ** inv[d21] ** C2 + inv[YY] ** B1 ** tp[B1] ** XX - 
   tp[C1] ** inv[tp[d12]] ** tp[B2] ** XX + 
   inv[1 - XX ** YY] ** tp[C2] ** inv[tp[d21]] ** inv[d21] ** C2 + 
   inv[1 - XX ** YY] ** tp[C2] ** inv[tp[d21]] ** tp[B1] ** XX - 
   XX ** B2 ** inv[d12] ** inv[tp[d12]] ** tp[B2] ** XX - 
   inv[1 - XX ** YY] ** XX ** YY ** tp[C2] ** inv[tp[d21]] ** 
   inv[d21] ** C2 - inv[1 - XX ** YY] ** XX ** YY ** tp[C2] ** 
   inv[tp[d21]] ** tp[B1] ** XX

In[10]:=SetOutput[dot -> True]
This does nothing but beautify the screen output.
In[11]:= NCBackward[ %9 ]
NCBackward will cause the inv[1-XX**YY] in the last two terms to hide behind the XX**YY, so that when we collect on inv[1-XX**YY] we will be extracting inv[1-XX**YY] and (1-XX**YY) at the same time.
Out[11]= -tp[C1] . C1 - XX . B2 . inv[d12] . C1 + 
   inv[YY] . B1 . inv[d21] . C2 + inv[YY] . B1 . tp[B1] . XX - 
   tp[C1] . inv[tp[d12]] . tp[B2] . XX + 
   inv[1 - XX . YY] . tp[C2] . inv[tp[d21]] . inv[d21] . C2 + 
   inv[1 - XX . YY] . tp[C2] . inv[tp[d21]] . tp[B1] . XX - 
   XX . B2 . inv[d12] . inv[tp[d12]] . tp[B2] . XX - 
   XX . YY . inv[1 - XX . YY] . tp[C2] . inv[tp[d21]] . inv[d21] . 
   C2 - XX . YY . inv[1 - XX . YY] . tp[C2] . inv[tp[d21]] . tp[B1] . 
   XX

In[12]:= NCC[ %, inv[1-XX**YY] ]

Out[12]= -tp[C1] . C1 - XX . B2 . inv[d12] . C1 + 
   inv[YY] . B1 . inv[d21] . C2 + inv[YY] . B1 . tp[B1] . XX - 
   tp[C1] . inv[tp[d12]] . tp[B2] . XX + 
   tp[C2] . inv[tp[d21]] . inv[d21] . C2 + 
   tp[C2] . inv[tp[d21]] . tp[B1] . XX - 
   XX . B2 . inv[d12] . inv[tp[d12]] . tp[B2] . XX
We are FINISHED simplifying according to some tastes, because all inv[1-XX**YY] terms are gone. There is ANOTHER WAY which works on some things but not others.
In[13]:= coexz

Out[13]= -tp[C1] . C1 - XX . B2 . inv[d12] . C1 - 
   tp[C1] . inv[tp[d12]] . tp[B2] . XX - 
   XX . inv[1 - YY . XX] . B1 . inv[d21] . C2 - 
   XX . inv[1 - YY . XX] . B1 . tp[B1] . XX + 
   inv[YY] . inv[1 - YY . XX] . B1 . inv[d21] . C2 + 
   inv[YY] . inv[1 - YY . XX] . B1 . tp[B1] . XX - 
   XX . B2 . inv[d12] . inv[tp[d12]] . tp[B2] . XX - 
   XX . inv[1 - YY . XX] . YY . tp[C2] . inv[tp[d21]] . inv[d21] . 
   C2 - XX . inv[1 - YY . XX] . YY . tp[C2] . inv[tp[d21]] . tp[B1] . 
   XX + inv[YY] . inv[1 - YY . XX] . YY . tp[C2] . inv[tp[d21]] . 
   inv[d21] . C2 + inv[YY] . inv[1 - YY . XX] . YY . tp[C2] . 
   inv[tp[d21]] . tp[B1] . XX

In[14]:= NCSimplifyRational[ coexz ]


Out[14]= -tp[C1] . C1 - XX . B2 . inv[d12] . C1 + 
   inv[YY] . B1 . inv[d21] . C2 + inv[YY] . B1 . tp[B1] . XX - 
   tp[C1] . inv[tp[d12]] . tp[B2] . XX + 
   tp[C2] . inv[tp[d21]] . inv[d21] . C2 + 
   tp[C2] . inv[tp[d21]] . tp[B1] . XX - 
   XX . B2 . inv[d12] . inv[tp[d12]] . tp[B2] . XX
WHAMMO! We got the answer Out[14] in one shot. The function NCSimplifyRational is based on automatically applying a carefully chosen collection of rules like NCBackward and In[9] repeatedly. Rules can be added so it should get better and better (that is, work well on many expressions.)

Now we turn to condensing the expression. It is a good exercise.

 
In[15]:= NCC[ %14, tp[C2] ** inv[tp[d21]]] 


Out[15]= -tp[C1] . C1 + tp[C2] . inv[tp[d21]] . 
   (inv[d21] . C2 + tp[B1] . XX) - XX . B2 . inv[d12] . C1 + 
   inv[YY] . B1 . inv[d21] . C2 + inv[YY] . B1 . tp[B1] . XX - 
   tp[C1] . inv[tp[d12]] . tp[B2] . XX - 
   XX . B2 . inv[d12] . inv[tp[d12]] . tp[B2] . XX

In[16]:= NCC[ %, inv[YY] ** B1 ]


Out[16]= -tp[C1] . C1 + inv[YY] . B1 . (inv[d21] . C2 + tp[B1] . XX) +
   tp[C2] . inv[tp[d21]] . (inv[d21] . C2 + tp[B1] . XX) - 
   XX . B2 . inv[d12] . C1 - tp[C1] . inv[tp[d12]] . tp[B2] . XX - 
   XX . B2 . inv[d12] . inv[tp[d12]] . tp[B2] . XX

In[17]:= NCC[ %, inv[tp[d12]] ]


Out[17]= -tp[C1] . C1 + inv[YY] . B1 . (inv[d21] . C2 + tp[B1] . XX) + 
   tp[C2] . inv[tp[d21]] . (inv[d21] . C2 + tp[B1] . XX) - 
   XX . B2 . inv[d12] . C1 - 
   (XX . B2 . inv[d12] + tp[C1]) . inv[tp[d12]] . tp[B2] . XX

In[18]:= NCC[ %, C1 ]


Out[18]= -(XX . B2 . inv[d12] + tp[C1]) . C1 + 
   inv[YY] . B1 . (inv[d21] . C2 + tp[B1] . XX) + 
   tp[C2] . inv[tp[d21]] . (inv[d21] . C2 + tp[B1] . XX) - 
   (XX . B2 . inv[d12] + tp[C1]) . inv[tp[d12]] . tp[B2] . XX

In[19]:= factor = %[[ 1,2,1 ]]
This is standard Mathematica, picking a part of an expression.
Out[19]= XX . B2 . inv[d12] + tp[C1]

In[20]:= NCC[ %%, factor ]


Out[20]= -(XX . B2 . inv[d12] + tp[C1]) . 
   (C1 + inv[tp[d12]] . tp[B2] . XX) + 
   inv[YY] . B1 . (inv[d21] . C2 + tp[B1] . XX) + 
   tp[C2] . inv[tp[d21]] . (inv[d21] . C2 + tp[B1] . XX)

In[21]:= factor = %[[ 2,3 ]] 

Out[21]= inv[d21] . C2 + tp[B1] . XX

In[22]:= NCC[ %%, factor ]


Out[22]= (inv[YY] . B1 + tp[C2] . inv[tp[d21]]) . 
   (inv[d21] . C2 + tp[B1] . XX) - 
   (XX . B2 . inv[d12] + tp[C1]) . (C1 + inv[tp[d12]] . tp[B2] . XX)
This is about as good as I can do.


next up previous contents index
Next: Vector Differentiation Up: Examples Previous: Examples   Contents   Index
NCAlgebra Project 2002-09-09