7

I would like to redefine the type of multiplication that is used in Det (calculates the determinant). Instead of the standard multiplication I would like to use a custom function Fun[a,b] (which takes two elements as input and outputs one element). Is it possible to somehow redefine the multiplication operator in Det?

Thanks a lot

ftiaronsem
  • 665
  • 4
  • 13
  • You probably need to reimplement it link – Kuba Oct 28 '14 at 16:00
  • Probably it would be good to explain what your ultimate goal is, and what the specific properties of the function Fun are. Without that information, there is a good chance that any effort to answer this could be misdirected. – Jens Oct 28 '14 at 18:01

2 Answers2

9

Here's a way that doesn't mess with an important system function:

Clear[a, times];
m = Array[a, {3, 3}];
TensorContract[
  Outer[times, Sequence @@ m] \[TensorProduct] LeviCivitaTensor[Length[m], List],
  Table[{i, i + Length[m]}, {i, Length[m]}]]
(*
times[a[1, 1], a[2, 2], a[3, 3]] - times[a[1, 1], a[2, 3], a[3, 2]] - 
 times[a[1, 2], a[2, 1], a[3, 3]] + times[a[1, 2], a[2, 3], a[3, 1]] +
  times[a[1, 3], a[2, 1], a[3, 2]] - times[a[1, 3], a[2, 2], a[3, 1]]
*)
Michael E2
  • 235,386
  • 17
  • 334
  • 747
7

In principle you can redefine safely a native function inside Block and given that Det uses Times for symbolic matrices then

Block[
 {Times = f}, Det[{{a, b}, {c, d}}]
 ]
f[a, d] + f[-1, b, c]

As pointed out by @Kuba and @Jens there are several limitations. A better solution would be this:

newDet[m_, f_] := Activate@(Block[{ms = Length[m], Times = f, a},
      Det@Table[Inactive[Part][a, i, j], {i, ms}, {j, ms}]] /. f[-1, x_, y_] -> -f[x, y] /. a -> m)

or

newDet[m_, f_] := 
 Activate@ReleaseHold@(Block[{ms = Length[m], Times = f},
      Det@Table[Inactive[Part][HoldForm[m], i, j], {i, ms}, {j, ms}]] /. f[-1, x_, y_] -> -f[x, y])

Now we can calculate the new determinant with an arbitrary function g

newDet[{{2 a, b}, {c, d}}, g]
g[2 a, d] - g[b, c]

More information about Block and how is different from With or Module in this answer

rhermans
  • 36,518
  • 4
  • 57
  • 149
  • Very nice. I was spending a stupid time making up a Det function – Dr. belisarius Oct 28 '14 at 16:04
  • But it probably should be -f[b,c] right? – Kuba Oct 28 '14 at 16:09
  • @rhermans yea, this may be easy. but what with Block[{Times = f}, Det[{{-a, b}, {c, d}}]] and the inner f? – Kuba Oct 28 '14 at 16:16
  • @Kuba, I see your point, I just took the literal request of "redefine the multiplication". Then we would need to do it in two ways, one for the matrix operations and other for all other factors. – rhermans Oct 28 '14 at 16:26
  • @rhermans Don't get me wrong :) +1ed of course. Just wanted to point those issues, maybe it matters for OP maybe not. – Kuba Oct 28 '14 at 16:28
  • Thanks a lot for the great answer. The first version is fully suitable for me. But why does "Block" have the HoldAll attribute? I ended up replacing "Block" with "With" in order to get my custom multiplication working. – ftiaronsem Oct 28 '14 at 17:52
  • @ftiaronsem I don't think I can explain why and how, but I have read that Block is the one to use to redefine native functions. See the link to a long explanation at the end of the answer. – rhermans Oct 28 '14 at 18:17
  • @Kuba I'm interested to know if you see further limitations to the current version. Cheers. – rhermans Oct 28 '14 at 18:19
  • 1
    The Block approach doesn't work for numerical matrices, e.g., Block[{Times = f}, Det[PauliMatrix[2]]] – Jens Oct 28 '14 at 19:07
  • 1
    Thanks again rhermans. I looked at the links you provided, but I am not still not entirely confident in the use of Block vs With. It is probably something that comes with experience. I decided to accept Michael's answer, since it worked better (less lines of code) for my application. But thanks a lot nonetheless! – ftiaronsem Oct 28 '14 at 19:15