josdejong / mathjs

An extensive math library for JavaScript and Node.js
https://mathjs.org
Apache License 2.0
14.44k stars 1.24k forks source link

Hermitian conjugate vs transpose #1094

Closed jackschmidt closed 6 years ago

jackschmidt commented 6 years ago

In matlab and octave the expression A' produces the Hermitian conjugate, the complex conjugate of the transpose. In mathjs 4.1.2, A' produces the transpose. Is it reasonable to adjust mathjs to match matlab?

The named functions in matlab and octave are transpose for the current behavior of mathjs and ctranspose for the behavior of matlab and octave.

https://www.mathworks.com/help/matlab/ref/ctranspose.html

josdejong commented 6 years ago

I'm open to changing this, makes sense to follow the "common" behavior. Will be a breaking change of course.

I think we should:

  1. Do a round over other math applications to see if they have the same behavior for A'
  2. If it's indeed the most common behavior, implement ctranspose in math.js and change A' to use ctranspose

Anyone interested in picking these points up?

ericman314 commented 6 years ago

I am not a mathematician, so I had to look this up on MathWorld:

It is almost always the case that the combined operation of taking the transpose and complex conjugate arises in physical or computation contexts and virtually never the transpose in isolation (Strang 1988, pp. 220-221).

So it seems like the conjugate transpose has much more significance than the transpose alone, particularly in quantum mechanics and linear algebra. The notation for it is different in each field, though no one uses A' specifically. But it is reasonable to follow Matlab and Octave.

jackschmidt commented 6 years ago

I made an attempt at task 2.

I also discovered a related bug in the Frobenius norm. The code on line 195 of lib/function/arithmetic/norm.js is comment with sqrt(sum(diag(x'x))) but this is only true for the conjugate transpose. The general formula is sqrt(sum(sum(pow(abs(a[i,j]),2),i=1..m),j=1..n)), the square root of the sum of the absolute values squared of the entries.

In mathjs 5.2.1:

math.eval('norm([[3+4i]],"fro")')
{ re: 3, im: 4 }

In matlab:

norm([[3+4i]],'fro')
ans =  5
josdejong commented 6 years ago

Sounds indeed like a good idea to implement and use ctranspose instead, thanks for looking this up @ericman314. Let's go for it.

jackschmidt commented 6 years ago

I think this is done. Thanks!