Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Complex dot product doesn't conjugate #1761

Closed
cshaa opened this issue Mar 2, 2020 · 6 comments · Fixed by #1773
Closed

Complex dot product doesn't conjugate #1761

cshaa opened this issue Mar 2, 2020 · 6 comments · Fixed by #1773
Labels

Comments

@cshaa
Copy link
Collaborator

cshaa commented Mar 2, 2020

Inner product on ℂ is supposed to be sesquilinear – it should conjugate one of the two vectors before multiplying them. Source.

const I = math.complex(0,1)
math.dot( [1,0], [I,0] ) // I
math.dot( [I,0], [1,0] ) // I

The current dot product clearly doesn't conjugate neither one of the vectors. This is also true of multiply(Vector, Vector) which apparently has a different implementation than dot.

While the Wikipedia article I linked uses the convention <v, w> = vᵀ w̅ (inner product is linear in the first argument and antilinear in the second argument), the opposite convention <v, w> = v⁺ w = v̅ ᵀ w is used as often, if not more. (For example in quantum mechanics, the first argument is exclusively antilinear.)

@josdejong
Copy link
Owner

Ah, that's interesting. The dot function simply uses multiply internally and doesn't do anything special for complex input values.

What would be needed to fix this behavior for complex values? Wrap the function in conj(...)?

@josdejong josdejong added the bug label Mar 7, 2020
@cshaa
Copy link
Collaborator Author

cshaa commented Mar 11, 2020

Yes, wrapping one of the vectors in conj would solve the issue. The question is:

  1. Do we mind changing the API? (This is potentialy a breaking change.)
  2. Which of the two vectors should be conjugated? (I strongly root for the first one.)

@josdejong
Copy link
Owner

Thanks Michal!

  1. Since the behavior changes (though you could maybe pitch it as a bug fix) I think it's best to make it a major, breaking change. Which is no problem at all, it's just changing a different number in the version number :)
  2. I'm not an expert on this subject, so I think it would be best to follow what other math applications do (Matlab, Mathematica, Python numpy, ...). What do you think?

@cshaa
Copy link
Collaborator Author

cshaa commented Mar 15, 2020

Making a survey on how other applications do it is always a good idea! I checked Mathematica, Matlab and two Python libraries – Numpy and Scipy. I was surprised that only two of these four tools had a sesquilinear dot product. Both of them conjugated the first vector.

Mathematica

Mathematica has a dot product which doesn't conjugate [discussion] [docs].

Matlab

Matlab conjugates the first argument [docs]

A = [1i 0];
B = [1 0];
dot(A, B)
% ans = 0.0000 - 1.0000i

Numpy

Numpy has two dot products. First one, dot, is meant for general N-dimensional arrays and it doesn't conjugate [docs]:

>>> np.dot([2j, 3j], [2j, 3j])
(-13+0j)

The second one is vdot and it performs “the dot product of two vectors”. It conjugates the first argument [docs]:

>>> a = np.array([1+2j,3+4j])
>>> b = np.array([5+6j,7+8j])
>>> np.vdot(a, b)
(70-8j)
>>> np.vdot(b, a)
(70+8j)

Sympy

Classic sympy doesn't conjugate [live]:

>>> M = Matrix([I, 0])
>>> M.dot(M)
-1

Sympy for QM conjugates symbolically, but since the operations are coordinate-independent, it's impossible to tell which of the vectors is conjugated [live]:

>>> from sympy.physics.quantum import *
>>> A = Ket('A'); B = Ket('B')
>>> conjugate( Dagger(A) * B ) == Dagger(B) * A
True

@josdejong
Copy link
Owner

Sorry for the late reply. Thanks @m93a this is a very clear and useful overview! .

So conclusions are:

  1. If we conjugate we do the first argument
  2. There is no standard behaviour in whether or not to conjugate. So we simply have to decide. I sort of like what Numpy does by simply offering two different implementations. I think though for mathjs it makes sense to offer just one solution which does conjugate, which will be a (small) breaking change in the current behavior. Do you agree? If so, I think Improve dot product #1773 is ready to be merged, right?

@cshaa
Copy link
Collaborator Author

cshaa commented Mar 26, 2020

Hey Jos,
Yes, I agree that in mathjs it makes sense to offer just one solution which does conjugate.
I also confirm that the PR is ready to be merged :)

@josdejong josdejong mentioned this issue Mar 29, 2020
3 tasks
@cshaa cshaa closed this as completed Sep 26, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants