Commit f5ee5d1b authored by Anton Akhmerov's avatar Anton Akhmerov
Browse files

Merge branch 'pytest' into 'master'

switch to py.test

Closes #37.

Thanks to @jbweston for setting up a proper CI image.

See merge request !21
parents 21d98499 e424bbd8
[run]
omit = */tests/*
......@@ -3,4 +3,4 @@ job:
- python3 setup.py build
- python3 setup.py build_ext -i
- make -C doc clean && make -C doc html
- nosetests3 --with-coverage --cover-package kwant
- py.test --cov=kwant kwant
\ No newline at end of file
......@@ -39,7 +39,7 @@ The following software is highly recommended though not strictly required:
footprint. (Kwant uses only the sequential, single core version
of MUMPS. The advantages due to MUMPS as used by Kwant are thus independent
of the number of CPU cores of the machine on which Kwant runs.)
* The `nose testing framework <http://nose.readthedocs.org/>`_ for running the
* The `py.test testing framework <http://http://pytest.org/>`_ for running the
tests included with Kwant.
In addition, to build a copy of Kwant that has been checked-out directly from
......@@ -152,7 +152,7 @@ root.
1. Install the required packages. On Debian-based systems like Ubuntu this can
be done by running the command ::
sudo apt-get install python-dev python-scipy python-matplotlib python-nose g++ gfortran libopenblas-dev liblapack-dev libmumps-scotch-dev
sudo apt-get install python3-dev python3-scipy python3-matplotlib python3-pytest g++ gfortran libopenblas-dev liblapack-dev libmumps-scotch-dev
2. Unpack Tinyarray, enter its directory. To build and install, run ::
......@@ -231,7 +231,7 @@ installed as ::
brew tap homebrew/science
brew tap homebrew/python
brew tap kwant-project/kwant
pip install nose six
pip install pytest pytest-runner six
brew install numpy scipy matplotlib
Note that during the installation you will be told which paths to add when you
......
import square
from pytest import raises
from numpy.testing import assert_almost_equal
def test_nodeid_to_from_pos():
s = square.System((3, 4), 1)
raises(Exception, s.nodeid_from_pos, (0, -2))
raises(Exception, s.nodeid_from_pos, (-1, 3))
raises(Exception, s.nodeid_from_pos, (3, 1))
raises(Exception, s.pos_from_nodeid, -1)
raises(Exception, s.pos_from_nodeid, 12)
assert s.nodeid_from_pos((0, 0)) == 0
assert s.nodeid_from_pos(s.pos_from_nodeid(7)) == 7
assert s.pos_from_nodeid(s.nodeid_from_pos((2, 3))) == (2, 3)
def test_hamiltonian():
sys = square.System((4, 5), 1)
for i in range(sys.graph.num_nodes):
shape = sys.hamiltonian(i, i).shape
assert len(shape) == 2
assert shape[0] == 1
for j in sys.graph.out_neighbors(i):
m = sys.hamiltonian(i, j)
shape = m.shape
m_herm = m.T.conj()
assert_almost_equal(m, m_herm)
assert_almost_equal(m_herm, sys.hamiltonian(j, i))
def test_selfenergy():
syst = square.System((2, 4), 1)
for lead in range(len(syst.lead_interfaces)):
se = syst.leads[lead].selfenergy(0)
assert len(se.shape) == 2
assert se.shape[0] == se.shape[1]
assert se.shape[0] == len(syst.lead_interfaces[lead])
import square
from nose.tools import assert_equal, assert_raises
from numpy.testing import assert_almost_equal
def test_nodeid_to_from_pos():
s = square.System((3, 4), 1)
assert_raises(Exception, s.nodeid_from_pos, (0, -2))
assert_raises(Exception, s.nodeid_from_pos, (-1, 3))
assert_raises(Exception, s.nodeid_from_pos, (3, 1))
assert_raises(Exception, s.pos_from_nodeid, -1)
assert_raises(Exception, s.pos_from_nodeid, 12)
assert_equal(s.nodeid_from_pos((0, 0)), 0)
assert_equal(s.nodeid_from_pos(s.pos_from_nodeid(7)), 7)
assert_equal(s.pos_from_nodeid(s.nodeid_from_pos((2, 3))), (2, 3))
def test_hamiltonian():
syst = square.System((4, 5), 1)
for i in range(syst.graph.num_nodes):
shape = syst.hamiltonian(i, i).shape
assert_equal(len(shape), 2)
assert_equal(shape[0], 1)
for j in syst.graph.out_neighbors(i):
m = syst.hamiltonian(i, j)
shape = m.shape
m_herm = m.T.conj()
assert_almost_equal(m, m_herm)
assert_almost_equal(m_herm, syst.hamiltonian(j, i))
def test_selfenergy():
syst = square.System((2, 4), 1)
for lead in range(len(syst.lead_interfaces)):
se = syst.leads[lead].selfenergy(0)
assert_equal(len(se.shape), 2)
assert_equal(se.shape[0], se.shape[1])
assert_equal(se.shape[0], len(syst.lead_interfaces[lead]))
......@@ -53,11 +53,11 @@ else:
__all__.extend(['plotter', 'plot'])
def test(verbose=1):
from nose.core import run
def test(verbose=True):
from pytest import main
import os.path
return run(argv=[__file__, os.path.dirname(os.path.abspath(__file__)),
"-s", "--verbosity="+str(verbose)])
return main([os.path.dirname(os.path.abspath(__file__)),
"-s"] + (['-v'] if verbose else []))
test.__test__ = False
......@@ -9,7 +9,7 @@
from io import StringIO
from itertools import zip_longest
import numpy as np
from nose.tools import assert_equal, assert_raises
from pytest import raises
from kwant.graph.core import (Graph, NodeDoesNotExistError,
EdgeDoesNotExistError, DisabledFeatureError)
......@@ -18,25 +18,25 @@ def test_empty():
g = graph.compressed()
assert not g.twoway
assert not g.edge_nr_translation
assert_raises(NodeDoesNotExistError, g.out_neighbors, 0)
assert_raises(NodeDoesNotExistError, g.has_edge, 0, 0)
assert_raises(DisabledFeatureError, g.edge_id, 0)
raises(NodeDoesNotExistError, g.out_neighbors, 0)
raises(NodeDoesNotExistError, g.has_edge, 0, 0)
raises(DisabledFeatureError, g.edge_id, 0)
g = graph.compressed(twoway=True, edge_nr_translation=True)
assert g.twoway
assert g.edge_nr_translation
assert_raises(NodeDoesNotExistError, g.in_neighbors, 0)
assert_raises(NodeDoesNotExistError, g.out_edge_ids, 0)
assert_raises(NodeDoesNotExistError, g.in_edge_ids, 0)
assert_raises(EdgeDoesNotExistError, g.edge_id, 0)
raises(NodeDoesNotExistError, g.in_neighbors, 0)
raises(NodeDoesNotExistError, g.out_edge_ids, 0)
raises(NodeDoesNotExistError, g.in_edge_ids, 0)
raises(EdgeDoesNotExistError, g.edge_id, 0)
def test_num_nodes():
graph = Graph()
assert_equal(graph.num_nodes, 0)
assert graph.num_nodes == 0
graph.num_nodes = 2
assert_equal(graph.num_nodes, 2)
assert_raises(ValueError, graph.__setattr__, 'num_nodes', 1)
assert graph.num_nodes == 2
raises(ValueError, graph.__setattr__, 'num_nodes', 1)
g = graph.compressed()
assert_equal(g.num_nodes, 2)
assert g.num_nodes == 2
def test_large():
num_edges = 1000
......@@ -45,15 +45,15 @@ def test_large():
graph.add_edge(i, i + 1)
g = graph.compressed()
g2 = graph.compressed(twoway=True)
assert_equal(num_edges, g.num_nodes - 1)
assert num_edges == g.num_nodes - 1
for i in range(num_edges):
assert_equal(tuple(g.out_neighbors(i)), (i + 1,))
assert_equal(tuple(g2.in_neighbors(i + 1)), (i,))
assert tuple(g.out_neighbors(i)) == (i + 1,)
assert tuple(g2.in_neighbors(i + 1)) == (i,)
def check_dot(dot_expect, graph):
output = StringIO()
graph.write_dot(output)
assert_equal(output.getvalue(), dot_expect)
assert output.getvalue() == dot_expect
output.close()
def test_small():
......@@ -72,55 +72,55 @@ def test_small():
g = g.compressed(twoway=True)
for edge_should, edge_is in zip_longest(edges, g):
assert_equal(edge_should, edge_is)
assert edge_should == edge_is
edge_ids = []
for edge in edges:
edge_ids.append(g.first_edge_id(*edge))
assert_equal(tuple(g.out_neighbors(0)), (1, 2))
assert_equal(tuple(g.in_neighbors(0)), ())
assert_equal(tuple(g.out_edge_ids(0)), (edge_ids[0], edge_ids[1]))
assert_equal(tuple(g.in_edge_ids(0)), ())
assert tuple(g.out_neighbors(0)) == (1, 2)
assert tuple(g.in_neighbors(0)) == ()
assert tuple(g.out_edge_ids(0)) == (edge_ids[0], edge_ids[1])
assert tuple(g.in_edge_ids(0)) == ()
assert_equal(tuple(g.out_neighbors(1)), (2,))
assert_equal(tuple(g.in_neighbors(1)), (0, 2))
assert_equal(tuple(g.out_edge_ids(1)), (edge_ids[2],))
assert_equal(tuple(g.in_edge_ids(1)), (edge_ids[0], edge_ids[3]))
assert tuple(g.out_neighbors(1)) == (2,)
assert tuple(g.in_neighbors(1)) == (0, 2)
assert tuple(g.out_edge_ids(1)) == (edge_ids[2],)
assert tuple(g.in_edge_ids(1)) == (edge_ids[0], edge_ids[3])
assert_equal(tuple(g.out_neighbors(2)), (1,))
assert_equal(tuple(g.in_neighbors(2)), (0, 1))
assert_equal(tuple(g.out_edge_ids(2)), (edge_ids[3],))
assert_equal(tuple(g.in_edge_ids(2)), (edge_ids[1], edge_ids[2]))
assert tuple(g.out_neighbors(2)) == (1,)
assert tuple(g.in_neighbors(2)) == (0, 1)
assert tuple(g.out_edge_ids(2)) == (edge_ids[3],)
assert tuple(g.in_edge_ids(2)) == (edge_ids[1], edge_ids[2])
assert g.has_edge(0, 1)
g.first_edge_id(0, 1)
assert not g.has_edge(1, 0)
assert_raises(IndexError, g.first_edge_id, 1, 0)
raises(IndexError, g.first_edge_id, 1, 0)
check_dot(dot_expect, g)
def test_negative_node_ids():
g = Graph()
assert_raises(ValueError, g.add_edge, 0, -1)
raises(ValueError, g.add_edge, 0, -1)
g = Graph(allow_negative_nodes=True)
g.add_edge(0, -1)
g.add_edge(-2, 0)
assert_raises(ValueError, g.add_edge, -3, -4)
assert_raises(ValueError, g.compressed)
raises(ValueError, g.add_edge, -3, -4)
raises(ValueError, g.compressed)
g1 = g.compressed(allow_lost_edges=True)
assert_equal(g1.num_px_edges, 1)
assert_equal(g1.num_xp_edges, 0)
assert g1.num_px_edges == 1
assert g1.num_xp_edges == 0
assert g1.has_edge(0, -1)
assert_raises(DisabledFeatureError, g1.has_edge, -2, 0)
assert_equal(tuple(g1.out_neighbors(0)), (-1,))
raises(DisabledFeatureError, g1.has_edge, -2, 0)
assert tuple(g1.out_neighbors(0)) == (-1,)
g2 = g.compressed(twoway=True)
assert_equal(g2.num_px_edges, 1)
assert_equal(g2.num_xp_edges, 1)
assert g2.num_px_edges == 1
assert g2.num_xp_edges == 1
assert g2.has_edge(0, -1)
assert g2.has_edge(-2, 0)
assert_equal(tuple(g2.out_neighbors(0)), (-1,))
assert_equal(tuple(g2.in_neighbors(0)), (-2,))
assert tuple(g2.out_neighbors(0)) == (-1,)
assert tuple(g2.in_neighbors(0)) == (-2,)
def test_add_edges():
edges = [(0, 1), (1, 2), (2, 3), (3, 0),
......@@ -143,39 +143,39 @@ def test_add_edges():
g.write_dot(output)
dot = output.getvalue()
if prev_dot is not None:
assert_equal(dot, prev_dot)
assert dot == prev_dot
prev_dot = dot
def test_edge_ids():
gr = Graph(allow_negative_nodes=True)
edges = [(0, -1), (-1, 0), (1, 2), (1, 2), (0, -1), (-1, 0), (-1, 0)]
for edge_nr, edge in enumerate(edges):
assert_equal(gr.add_edge(*edge), edge_nr)
assert gr.add_edge(*edge) == edge_nr
g = gr.compressed(twoway=True, edge_nr_translation=True)
assert g.twoway
assert g.edge_nr_translation
assert_equal(sorted(g.out_edge_ids(1)), sorted(g.in_edge_ids(2)))
assert sorted(g.out_edge_ids(1)) == sorted(g.in_edge_ids(2))
for edge_id in g.out_edge_ids(1):
assert_equal(g.tail(edge_id), 1)
assert_equal(g.head(edge_id), 2)
assert g.tail(edge_id) == 1
assert g.head(edge_id) == 2
for i, edge_id in enumerate(g.all_edge_ids(0, -1)):
if i == 0:
assert_equal(edge_id, g.first_edge_id(0, -1))
assert_equal(g.tail(edge_id), 0)
assert_equal(g.head(edge_id), -1)
assert_equal(i, 1)
assert edge_id == g.first_edge_id(0, -1)
assert g.tail(edge_id) == 0
assert g.head(edge_id) == -1
assert i == 1
for i, edge_id in enumerate(g.all_edge_ids(-1, 0)):
if i == 0:
assert_equal(edge_id, g.first_edge_id(-1, 0))
assert_equal(g.tail(edge_id), None)
assert_equal(g.head(edge_id), 0)
assert_equal(i, 2)
assert edge_id == g.first_edge_id(-1, 0)
assert g.tail(edge_id) == None
assert g.head(edge_id) == 0
assert i == 2
for edge_nr, edge in enumerate(edges):
if edge[0] < 0: continue
edge_id = g.edge_id(edge_nr)
assert_equal(edge, (g.tail(edge_id), g.head(edge_id)))
assert edge == (g.tail(edge_id), g.head(edge_id))
g = gr.compressed(edge_nr_translation=True, allow_lost_edges=True)
assert_raises(EdgeDoesNotExistError, g.edge_id, 1)
raises(EdgeDoesNotExistError, g.edge_id, 1)
......@@ -6,7 +6,6 @@
# the file AUTHORS.rst at the top-level directory of this distribution and at
# http://kwant-project.org/authors.
from nose.tools import assert_true
import numpy as np
# from kwant.graph import Graph, dissection
# from kwant.graph.dissection import edge_dissection
......@@ -41,4 +40,4 @@ def _DISABLED_test_edge_dissection():
found[entry] += 1
parse_tree(tree)
assert_true((found == 1).all())
assert (found == 1).all()
......@@ -6,7 +6,6 @@
# the file AUTHORS.rst at the top-level directory of this distribution and at
# http://kwant-project.org/authors.
from nose.tools import assert_true
from kwant.graph import Graph
# from kwant.graph.scotch import bisect, reset
......@@ -30,7 +29,7 @@ def _DISABLED_test_bisect():
parts = bisect(g)
for i in range(g.num_nodes):
assert_true(parts[i] == 0 or parts[i] == 1)
assert parts[i] == 0 or parts[i] == 1
def _DISABLED_test_reset():
size = 5
......@@ -53,4 +52,4 @@ def _DISABLED_test_reset():
reset()
parts2 = bisect(g)
assert_true((parts1 == parts2).all())
assert (parts1 == parts2).all()
......@@ -7,7 +7,6 @@
# http://kwant-project.org/authors.
import numpy as np
from nose.tools import assert_equal, assert_true
from kwant.graph import Graph
from kwant.graph.utils import (make_undirected, remove_duplicates,
induced_subgraph)
......@@ -24,36 +23,36 @@ def test_make_undirected():
# First, test with no duplicates removed,
g2 = make_undirected(g, remove_dups=False)
assert_equal(g2.num_nodes, g.num_nodes)
assert_equal(g2.num_edges, 6)
assert_true(g2.has_edge(0, 1))
assert_true(g2.has_edge(1, 0))
assert_true(g2.has_edge(1, 2))
assert_true(g2.has_edge(2, 1))
assert g2.num_nodes == g.num_nodes
assert g2.num_edges == 6
assert g2.has_edge(0, 1)
assert g2.has_edge(1, 0)
assert g2.has_edge(1, 2)
assert g2.has_edge(2, 1)
# then with duplicates removed,
g2 = make_undirected(g, remove_dups=True)
assert_equal(g2.num_nodes, g.num_nodes)
assert_equal(g2.num_edges, 4)
assert_true(g2.has_edge(0, 1))
assert_true(g2.has_edge(1, 0))
assert_true(g2.has_edge(1, 2))
assert_true(g2.has_edge(2, 1))
assert g2.num_nodes == g.num_nodes
assert g2.num_edges == 4
assert g2.has_edge(0, 1)
assert g2.has_edge(1, 0)
assert g2.has_edge(1, 2)
assert g2.has_edge(2, 1)
# and finally with weights.
g2, edge_w2 = make_undirected(g, remove_dups=True, calc_weights=True)
assert_equal(g2.num_nodes, g.num_nodes)
assert_equal(g2.num_edges, 4)
assert_true(g2.has_edge(0, 1))
assert_true(g2.has_edge(1, 0))
assert_true(g2.has_edge(1, 2))
assert_true(g2.has_edge(2, 1))
assert_equal(edge_w2[g2.first_edge_id(0,1)], 2)
assert_equal(edge_w2[g2.first_edge_id(1,0)], 2)
assert_equal(edge_w2[g2.first_edge_id(1,2)], 1)
assert_equal(edge_w2[g2.first_edge_id(2,1)], 1)
assert g2.num_nodes == g.num_nodes
assert g2.num_edges == 4
assert g2.has_edge(0, 1)
assert g2.has_edge(1, 0)
assert g2.has_edge(1, 2)
assert g2.has_edge(2, 1)
assert edge_w2[g2.first_edge_id(0,1)] == 2
assert edge_w2[g2.first_edge_id(1,0)] == 2
assert edge_w2[g2.first_edge_id(1,2)] == 1
assert edge_w2[g2.first_edge_id(2,1)] == 1
def test_remove_duplicates():
graph = Graph()
......@@ -64,19 +63,19 @@ def test_remove_duplicates():
# First test without edge weights,
g = graph.compressed()
remove_duplicates(g)
assert_equal(g.num_edges, 2)
assert_true(g.has_edge(0, 1))
assert_true(g.has_edge(1, 2))
assert g.num_edges == 2
assert g.has_edge(0, 1)
assert g.has_edge(1, 2)
# then with edge weights.
g = graph.compressed()
edge_w = np.array([1,1,1], dtype=gint_dtype)
remove_duplicates(g, edge_w)
assert_equal(g.num_edges, 2)
assert_true(g.has_edge(0, 1))
assert_true(g.has_edge(1, 2))
assert_equal(edge_w[g.first_edge_id(0,1)], 2)
assert_equal(edge_w[g.first_edge_id(1,2)], 1)
assert g.num_edges == 2
assert g.has_edge(0, 1)
assert g.has_edge(1, 2)
assert edge_w[g.first_edge_id(0,1)] == 2
assert edge_w[g.first_edge_id(1,2)] == 1
def test_induced_subgraph():
......@@ -91,44 +90,38 @@ def test_induced_subgraph():
# First test select array,
select = np.array([True, True, True, False, False, True])
g2 = induced_subgraph(g, select)
assert_equal(g2.num_nodes, 4)
assert_equal(g2.num_edges, 3)
assert_true(g2.has_edge(0, 1))
assert_true(g2.has_edge(1, 0))
assert_true(g2.has_edge(1, 2))
assert g2.num_nodes == 4
assert g2.num_edges == 3
assert g2.has_edge(0, 1)
assert g2.has_edge(1, 0)
assert g2.has_edge(1, 2)
# then test select function.
g2 = induced_subgraph(g, lambda i: select[i])
assert_equal(g2.num_nodes, 4)
assert_equal(g2.num_edges, 3)
assert_true(g2.has_edge(0, 1))
assert_true(g2.has_edge(1, 0))
assert_true(g2.has_edge(1, 2))
assert g2.num_nodes == 4
assert g2.num_edges == 3
assert g2.has_edge(0, 1)
assert g2.has_edge(1, 0)
assert g2.has_edge(1, 2)
# Now the same with edge weights.
edge_w = np.arange(g.num_edges, dtype=gint_dtype)
g2, edge_w2 = induced_subgraph(g, select, edge_w)
assert_equal(g2.num_nodes, 4)
assert_equal(g2.num_edges, 3)
assert_true(g2.has_edge(0, 1))
assert_true(g2.has_edge(1, 0))
assert_true(g2.has_edge(1, 2))
assert_equal(edge_w[g.first_edge_id(0,1)],
edge_w2[g2.first_edge_id(0,1)])
assert_equal(edge_w[g.first_edge_id(1,0)],
edge_w2[g2.first_edge_id(1,0)])
assert_equal(edge_w[g.first_edge_id(1,2)],
edge_w2[g2.first_edge_id(1,2)])
assert g2.num_nodes == 4
assert g2.num_edges == 3
assert g2.has_edge(0, 1)
assert g2.has_edge(1, 0)
assert g2.has_edge(1, 2)
assert edge_w[g.first_edge_id(0,1)] == edge_w2[g2.first_edge_id(0,1)]
assert edge_w[g.first_edge_id(1,0)] == edge_w2[g2.first_edge_id(1,0)]
assert edge_w[g.first_edge_id(1,2)] == edge_w2[g2.first_edge_id(1,2)]
g2, edge_w2 = induced_subgraph(g, lambda i: select[i], edge_w)
assert_equal(g2.num_nodes, 4)
assert_equal(g2.num_edges, 3)
assert_true(g2.has_edge(0, 1))
assert_true(g2.has_edge(1, 0))
assert_true(g2.has_edge(1, 2))
assert_equal(edge_w[g.first_edge_id(0,1)],
edge_w2[g2.first_edge_id(0,1)])
assert_equal(edge_w[g.first_edge_id(1,0)],
edge_w2[g2.first_edge_id(1,0)])
assert_equal(edge_w[g.first_edge_id(1,2)],
edge_w2[g2.first_edge_id(1,2)])
assert g2.num_nodes == 4
assert g2.num_edges == 3
assert g2.has_edge(0, 1)
assert g2.has_edge(1, 0)
assert g2.has_edge(1, 2)
assert edge_w[g.first_edge_id(0,1)] == edge_w2[g2.first_edge_id(0,1)]
assert edge_w[g.first_edge_id(1,0)] == edge_w2[g2.first_edge_id(1,0)]
assert edge_w[g.first_edge_id(1,2)] == edge_w2[g2.first_edge_id(1,2)]
......@@ -10,7 +10,6 @@ from kwant.linalg import (
lu_factor, lu_solve, rcond_from_lu, gen_eig, schur,
convert_r2c_schur, order_schur, evecs_from_schur, gen_schur,
convert_r2c_gen_schur, order_gen_schur, evecs_from_gen_schur)
from nose.tools import assert_equal, assert_true
import numpy as np
from ._test_utils import _Random, assert_array_almost_equal
......@@ -79,8 +78,8 @@ def test_rcond_from_lu():
#the assertions here
#Note: in my experience the estimate is excellent for somewhat
#larger matrices
assert_true(err1/rcond1 < 0.1)
assert_true(errI/rcondI < 0.1)
assert err1/rcond1 < 0.1
assert errI/rcondI < 0.1
_test_rcond_from_lu(np.float32)
_test_rcond_from_lu(np.float64)
......@@ -174,8 +173,8 @@ def test_evecs_from_schur():
vl, vr = evecs_from_schur(t, q, select, left=True, right=True)
assert_equal(vr.shape[1], 2)
assert_equal(vl.shape[1], 2)
assert vr.shape[1] == 2
assert vl.shape[1] == 2
assert_array_almost_equal(dtype, np.dot(a, vr),
np.dot(vr, np.diag(ev[select])))
assert_array_almost_equal(dtype, np.dot(vl.T.conj(), a),
......@@ -183,8 +182,8 @@ def test_evecs_from_schur():
vl, vr = evecs_from_schur(t, q, lambda i: i<2, left=True, right=True)
assert_equal(vr.shape[1], 2)
assert_equal(vl.shape[1], 2)
assert vr.shape[1] == 2
assert vl.shape[1] == 2
assert_array_almost_equal(dtype, np.dot(a, vr),
np.dot(vr, np.diag(ev[select])))