# How to simplify the result of matrix according to the operation rules specified in the textbook?

We know that the inverse and transposition of composite matrices follow certain calculation rules. For example, $$(ABC)^{-1}=(C^{-1})(B^{-1})(A^{-1})$$, $$(ABC)^T=C^TB^TA^T$$, $$ABC=E \Rightarrow BCA=E$$.

Inverse[A.B.CC]


How can I simplify the result of matrix operation with these calculation rules?

Inverse[(A.B.CC)]\[Transpose].CC\[Transpose]

trans[A_⊗B_] := trans[B]⊗trans[A]
inv[A_⊗B_] := inv[B]⊗inv[A]
adj[A_] := Det[A]*inv[A]
adj[A⊗B⊗CC]

SuperStar[(a⊗b⊗c)] //.
SuperStar[CircleTimes[A_, B__]] :>
CircleTimes[SuperStar[CircleTimes[B]], SuperStar[A]]


I have tried some methods to solve this problem, but I have encountered some difficulties because I have no previous experience in using custom operation rules to simplify the results, so I need your help.

• What have you tried? This is not a mechanical turk site.
– ciao
Commented Sep 2, 2020 at 4:57
• @ciao I apologize for this poor question. I'm updating it. Commented Sep 2, 2020 at 5:21
• You should be more specific what you want to define and what you want to derive from those definitions. Commented Sep 2, 2020 at 6:43
• @Natas Thank you for your comments. I want to start with the simplest rule, such as using the rule $(AB)^{-1}=(B^{-1})(A^{-1})$ to get $(ABC)^{-1} \Rightarrow (C^{-1})(B^{-1})(A^{-1})$. More rules will be added later. Commented Sep 2, 2020 at 7:43

## 2 Answers

The approach that I take with this kind of problem is to define rules and apply them in an intelligent sequence (taking account that the rules are only valid with additional conditions, such as the matrices being square).

For your example

example = Transpose[Inverse[A.B.CC]].Transpose[CC];


I might define the following rules

distributeinverseoverdot = {Inverse[Dot[a_, b__]] :>
Inverse[Dot[b]].Inverse[a]};
distributetransposeoverdot = {Transpose[Dot[a_, b__]] :>
Transpose[Dot[b]].Transpose[a]};
inversetransposein = {Transpose[Inverse[a_]] -> Inverse[Transpose[a]]};
anihilateinverse = {Dot[a___, Inverse[b_], b_, c___] :> Dot[a, c],
Dot[a___, b_, Inverse[b_], c___] :> Dot[a, c]};


which bring it to a reasonable simplest form

example //. distributeinverseoverdot //.
distributetransposeoverdot /. inversetransposein /. anihilateinverse
(* Inverse[Transpose[A]].Inverse[Transpose[B]] *)


Of course, with additional rules, you could take the transpose and inverse back out again.

Working with rules is much simpler to debug, and makes it much easier to tune the result to exactly what you want.

A method provided by someone else:

   f[e_] := -LeafCount[SuperStar /@ Dot[e]]
FullSimplify[SuperStar[a.b.c],
TransformationFunctions -> {# //.
SuperStar[Dot[A_, B__]] :>
Dot[SuperStar[Dot[B]], SuperStar[A]] &}, ComplexityFunction -> f]
f[SuperStar[(a.b.c)]]

g[e_] := LeafCount[SuperStar /@ Dot[e]]
FullSimplify[
SuperStar[a].SuperStar[b].Inverse[a.b] - (SuperStar[b.a]).Inverse[
b].Inverse[a],
TransformationFunctions -> {Automatic, # /.
Inverse[Dot[any__, rest_]] :>
Dot[Inverse[rest], Inverse[any]] &, # /.
SuperStar[Dot[any__, rest_]] :>
Dot[SuperStar[rest], SuperStar[any]] &, # /.
Inverse[rest_].Inverse[any_] :> Inverse[(any).(rest)] &, # /.
SuperStar[rest_].SuperStar[any_] :> SuperStar[(any).(rest)] &},
ComplexityFunction -> g]


I hope to get more ingenious ways to solve this problem with your help.