1
$\begingroup$

The following function can be plotted without any issues, say with ContourPlot, but NIntegrate fails because it tries to diagonalise the matrix with generic values x,y, instead of using numerical values.

del1 = {1, 0}; del2 = {1, Sqrt[3]}/2; del3 = del2 - del1;

matrix[k_] := {{1, Cos[k.del3/2],Cos[k.del1/2]},
  {Cos[k.del3/2],1,Cos[k.del2/2]}, {Cos[k.del1/2], Cos[k.del2/2], 1}};

fun[k_] := Block[{d = 0, abc, esys, UU},
  esys = Eigensystem[N[matrix[k]]];
  UU = Transpose[Normalize /@ esys[[2]]];
  abc = ConjugateTranspose[UU].DiagonalMatrix[{.1, 5, 0}].UU;
  abc[[1, 1]]]

NIntegrate[fun[{x, y}], {x, .3, .4}, {y, .3, .4}]

I have tried putting Evaluate and ?NumericQ in a few places, to no avail. How can I perform the desired integral?

$\endgroup$
  • 2
    $\begingroup$ Try ClearAll[fun]; before defining fun to erase all previous defs. Then fun[k_?(VectorQ[#, NumericQ] &)] := ... seems to work for me. $\endgroup$ – Michael E2 Jan 15 '18 at 15:53
  • $\begingroup$ Thanks Michael, this does indeed work. I would have never guessed that... Any reason why NIntegrate needs this but ContourPlot doesn't? $\endgroup$ – Daniel Jan 15 '18 at 16:02
  • 1
    $\begingroup$ I can't really explain it. Generally you've got solver[f[x], domain], where solver might be NIntegrate, ContourPlot, etc. The solver holds the code f (it does not evaluate immediately). Now, sometimes you want the solver to evaluate f and analyze the result (e.g., for method selection, to handle singularities); sometimes not. The other choice is whether the solver uses the evaluated code f or uses the original code for numeric evaluation. I think this choice is the difference, but I can't explain why ContourPlot chooses a different way from NIntegrate. $\endgroup$ – Michael E2 Jan 15 '18 at 16:49
  • $\begingroup$ Related/duplicate: mathematica.stackexchange.com/q/16694, mathematica.stackexchange.com/a/26037 $\endgroup$ – Michael E2 Jan 15 '18 at 19:00
0
$\begingroup$

This works.

del1 = {1, 0}; del2 = {1, Sqrt[3]}/2; del3 = del2 - del1;

matrix[k : {_?NumericQ, _?NumericQ}] := 
 {{1, Cos[k.del3/2], Cos[k.del1/2]}, 
  {Cos[k.del3/2], 1, Cos[k.del2/2]}, 
  {Cos[k.del1/2], Cos[k.del2/2], 1}}

fun[k : {_?NumericQ, _?NumericQ}] :=
  Module[{d = 0, abc, esys, UU},
    esys = Eigensystem[N[matrix[k]]];
    UU = Transpose[Normalize /@ esys[[2]]];
    abc = ConjugateTranspose[UU].DiagonalMatrix[{.1, 5, 0}].UU;
    abc[[1, 1]]]

NIntegrate[fun[{x, y}], {x, .3, .4}, {y, .3, .4}]

0.0170039

Note: The argument pattern given in the definitions of matrix and fun is the critical change. The change of Block to Module is not critical; I just think it is better practice in this case.

| improve this answer | |
$\endgroup$

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