I want to define simple matrix algebra (inspired by the following posts: Block Matrix Algebra with Mathematica ; How to define custom operators ).

I assume the funtion MatrixMult[A_,B_] to be the matrix product. I surely can define some properties of this function, like linearity, associativity etc. (see referenced posts). Now I want to solve simple matrix equation

Solve[MatrixMult[A, X]==B,X]

Obviously, the answer is

{{X -> InverseFunction[MatrixMult, 2, 2][A, B]}}

Now the question is how can I explicitly define that the inverse of my function is the following:

InverseFunction[MatrixMult, 2, 2][A_, B_] := MatrixMult[Inverse[A], B]

(the last line results in "Tag InverseFunction is Protected" error)

  • $\begingroup$ Either unprotect the symbol or change the name of your predicate. Also look up What are the most common pitfalls ... thread and see the difference between = and := when defining predicates. $\endgroup$
    – Sektor
    Mar 3, 2014 at 10:22
  • $\begingroup$ I get the idea about Unprotect, but still couldn't get it work. After I define the inverse function (with SetDelayed) the Solve function returns {}. What do you mean by "change the name of your predicate"? $\endgroup$
    – bcp
    Mar 3, 2014 at 10:59
  • $\begingroup$ Well, InverseFunction is a built-in predicate, so you can't just use it overwrite it. $\endgroup$
    – Sektor
    Mar 3, 2014 at 11:05
  • $\begingroup$ Both Solve and InverseFunction are meant to be used with scalars only. What you are asking for would not be useful in this specific situation. For symbolic matrix algebra, google for the NCAlgebra package. $\endgroup$
    – Szabolcs
    Mar 3, 2014 at 14:30
  • 1
    $\begingroup$ Redefining built-ins is usually not a good idea, as it might break random and unexpected things. (This is a good example: Solve won't even return the InverseFunction any more.) What you could do instead is use a replacement rule that is not tied to InverseFunction and apply it manually, i.e. result /. InverseFunction[MatrixMult, 2, 2][A_, B_] :> MatrixMult[Inverse[A], B]. $\endgroup$
    – Szabolcs
    Mar 3, 2014 at 21:34

1 Answer 1


One can use UpValues to control the behavior of your MatrixMult function. We also need to teach MatrixMult how to handle Inverse as well:

MatrixMult[a_, MatrixMult[Inverse[a_], b_]] := b

MatrixMult /: InverseFunction[MatrixMult, 2, 2] = MatrixMult[Inverse[#1], #2]&

Notice that I don't try to give a definition for InverseFunction[MatrixMult, 2, 2][a_, b_] because then MatrixMult is buried to deep for UpValues to work. Now, let's try using Solve:

Solve[MatrixMult[A, X] == B, X]

Solve::ifun: Inverse functions are being used by Solve, so some solutions may not be found; use Reduce for complete solution information.

{{X -> MatrixMult[Inverse[A], B]}}

One could avoid the message by explicitly telling Solve that you want to use inverse functions:

Solve[MatrixMult[A, X] == B, X, InverseFunctions->True]

{{X -> MatrixMult[Inverse[A], B]}}


The MatrixMult DownValues above is needed because Solve tries to verify its solution. An alternative to giving MatrixMult the above DownValues is to tell Solve not to verify its solution:

MatrixMult /: InverseFunction[MatrixMult, 2, 2] = MatrixMult[Inverse[#1], #2]&;

Solve[MatrixMult[A, X] == B, X, InverseFunctions->True, VerifySolutions->False] 

{{X -> MatrixMult[Inverse[A], B]}}


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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