In the documentation of numerical_integral
there is no explicit statement that the function should be (defined on some proper or improper interval) with values in $\mathbb R$, but the following sentences in the doc string strongly suggest this is the case:
Note the coercion to the real field RR, which prevents underflow:
sage: f = exp(-x**2)
sage: numerical_integral(f, -Infinity, +Infinity) # random output
(1.7724538509060035, 3.4295192165889879e-08)
and
One can integrate any real-valued callable function:
sage: numerical_integral(lambda x: abs(zeta(x)), [1.1,1.5]) # random output
(1.8488570602160455, 2.052643677492633e-14)
In our case the solution / a work-around is simple, we just isolate the imaginary and the real parts of the function to be integrated.
sage: f(x) = (exp(i*x) + exp(-i*x))/2
sage: numerical_integral( real(f), (0,1) )
(0.8414709848078964, 9.342204618877319e-15)
sage: numerical_integral( imag(f), (0,1) )
(0.0, 0.0)
which matches
sage: numerical_integral( cos(x), (0,1) )
(0.8414709848078964, 9.342204618877319e-15)
Further examples with different, but similar data:
sage: numerical_integral( lambda x: exp(i*x).real(), (0, pi/6) )
(0.4999999999999999, 5.551115123125781e-15)
sage: numerical_integral( lambda x: exp(i*x).imag(), (0, pi/6) )
(0.13397459621556138, 1.487416814333746e-15)