Why the sign of eigenfunctions obtained from NDEigensystem are flipped

I am trying to verify my hand solution for a HW problem using Mathematica.

I noticed that I get correct eigenvalues from Mathematica using DEigenvalues but when looking at the eigenfunctions, using same operator, using NDEigensystem and when I ask for first eigenfunction, it gives correct one, when I ask for the first two, now they get flipped upside down !

They are correct, but needed to multiply them all by minus sign to get same result as hand solution.

Why does this happen?

Here is the problem to find its eigenvalues and eigefunctions.

\begin{align*} y''(x) + \lambda y(x) &= 0 \\ y(0)-y'(0) &=0\\ y(\pi)-y'(\pi) &=0 \end{align*}

Eigenvalues are $\lambda=-1$ and $\lambda=n^2$ for $n=1,2,3,\dots$. Mathematica agrees:

ClearAll[y,x];
op={-y''[x]+NeumannValue[y[x],x==0]-NeumannValue[y[x],x==Pi]};
eig=N[DEigenvalues[op,y[x],{x,0,Pi},6]]


So, assuming I did everyhing OK so far, lets now look at eigfunction associated with $\lambda=-1$. Mathematica finds this to be $e^x$ which is correct, but only when asking for the first one: (notice, there is normalization term, which can be ignored. Just looking at the shape).

 eigFunctions=Last@NDEigensystem[op,y,{x,0,Pi},1]
Plot[eigFunctions[[1]][x],{x,0,Pi}]


Now notice what happens when asking for the first two

 eigFunctions=Last@NDEigensystem[op,y,{x,0,Pi},2]
Plot[eigFunctions[[1]][x],{x,0,Pi}]


It flipped! The correct one is $e^x$ and not $-e^x$, as Mathematica verifies:

ClearAll[y,x];
lam=-1;
ode=y''[x]+ lam y[x]==0;
bc={y[0]-y'[0]==0,y[Pi]-y'[Pi]==0};
DSolve[{ode,bc},y[x],x]


Question is: Why do eigenfunctions from NDEigensystem are flipped when asking for more than one? They all get flipped, not just the first one.

Mathematica 11.3, windows 7.

• Well, I'm not quite familiar with eigenvalue problem, but if I've understood definition of eigenfunction correctly, any function that fits the form C[1] Exp[x] is the corresponding eigenfunction for $\lambda=-1$ in your case, am I missing something? – xzczd Apr 12 '18 at 4:48
• @xzczd my question is why when asking for first eigenfunction, it shows as $\exp(x)$, but when asking for the first two eigenfunctions, it shows the first now as $-\exp(x)$. Why did the sign change? The book says also it should be $\exp(x)$ and not $-\exp(x)$. May be in theory both are valid (have to ask the teacher about this), but why did Mathematica give one sign one time and another sign the next time? – Nasser Apr 12 '18 at 4:51
• This is a peculiarity of the algorithm. It not wrong. So it can flip signs as it likes. Note that NIntegrate[# Conjugate[#], {x, 0, π}] & /@ Through[eigFunctions[x]] gives 1 for every eigenfunction. – user21 Apr 12 '18 at 5:32
• This happens ubiquitously in eigenvalue problems. It can depend on the number of eigenfunctions you require and also parameters in the equation. Quite annoying if you wish to make an animation of eigenfunctions (many sudden changes due to flips). It's nothing wrong albeit hard to control. – xiaohuamao Apr 13 '18 at 0:46
• @xiaohuamiao yes, I understand. This is like having an indefinite integral that return a constant of integration. One time you call it, it returns 10 as constant of the integration. Next time, it returns -10 or 99 or 20.34, all are correct. But all what I am saying, it is nice to return the same thing, that is all. I understand it is hard to control when there are many algorithms involved. I am just talking from user point of view. Not an internal/implementation point of view. – Nasser Apr 13 '18 at 7:15

First of all, as mentioned in the comment above, $-e^x$ is not wrong, and any function that fits the form $c_1 e^x$ ($c_1$ is non-zero, of course) is the corresponding eigenfunction for $\lambda=-1$ in your case, according to the definition of eigenfunction. Then why doesn't NDEigensystem always give the same form? I don't have a complete answer, the only thing I know is, the sign is inherited from Eigensystem together with "Arnoldi" method:

internal = Trace[NDEigensystem[op, y, {x, 0, Pi}, 2], HoldPattern@Eigensystem[__]] //
Flatten


internal[[1]] // ReleaseHold // Transpose // Last
(* {-0.999999, {-0.0164892, -0.0192938, -0.0225755, -0.0264153, …… *)

internal[[1, 1, 2]] = -1;
internal[[1]] // ReleaseHold
(* {{-0.999999}, {{0.0164892, 0.0192938, 0.0225755, …… *)

internal[[1]] /. (Method -> a_) :> Sequence[] // ReleaseHold
(* {{-0.999999}, {{-0.0164892, -0.0192938, -0.0225755, -0.0264153, …… *)

• Ok, thanks. My main complaint was it that Mathematica gives different result depending if user asked for one or two. This is just confusing from user point of view, even though it is theoretically correct. I think it should stick to one sign and not change it depending on how many the user wanted. But it looks like this is how it is designed to work. Ok. Just confuses one. – Nasser Apr 12 '18 at 5:39