Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions spatialmath/base/argcheck.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,8 @@ def getmatrix(
:raises ValueError: if value is not of the specified shape

``getmatrix(m, shape)`` is a 2D matrix with shape ``shape`` formed from
``m`` which can be a 2D array, 1D array-like or a scalar.
``m`` which can be a 2D array, a list or tuple of rows, a 1D array-like
(including a ``range``) or a scalar.

.. runblock:: pycon

Expand All @@ -197,6 +198,7 @@ def getmatrix(
>>> getmatrix([3,4], (2, 1))
>>> getmatrix([3,4,5,6], (2,2))
>>> getmatrix(np.r_[3,4,5,6], (2,2))
>>> getmatrix([[0,1,2], [0,1,0]], (2,None)) # list of rows

.. note::

Expand All @@ -213,6 +215,13 @@ def getmatrix(
:seealso: :func:`ismatrix`, :func:`verifymatrix`
:SymPy: supported
"""
if isinstance(m, range):
m = list(m)
if isinstance(m, (list, tuple)) and not isvector(m):
# passed a nested sequence, such as a list of rows: convert it and
# check its shape below
m = np.array(m)

if isinstance(m, np.ndarray) and len(m.shape) == 2:
# passed a 2D array
mshape = m.shape
Expand Down Expand Up @@ -341,7 +350,7 @@ def getvector(
where ``vec`` is any of:

- a Python native int or float, a 1-vector
- Python native list or tuple
- Python native list, tuple or range
- numPy real 1D array, ie. shape=(N,)
- numPy real 2D array with a singleton dimension, ie. shape=(1,N)
or (N,1)
Expand Down Expand Up @@ -386,6 +395,8 @@ def getvector(
"""
dt = dtype

if isinstance(v, range): # a range is a sequence of numbers
v = list(v)
if isinstance(v, _scalartypes): # handle scalar case
v = [v] # type: ignore
if isinstance(v, (list, tuple)):
Expand Down
39 changes: 39 additions & 0 deletions tests/base/test_argcheck.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,31 @@ def test_getmatrix(self):
with self.assertRaises(ValueError):
m = getmatrix(a, (2, None))

def test_getmatrix_nested_sequence(self):
# a list of rows, as for a 2xN path of points (issue #255)
m = getmatrix([[0, 1, 2], [0, 1, 0]], (2, None))
self.assertIsInstance(m, np.ndarray)
nt.assert_array_equal(m, np.array([[0, 1, 2], [0, 1, 0]]))
self.assertEqual(m.dtype, np.float64)

# a list of tuples, Nx2
m = getmatrix([(0, 0), (1, 1), (2, 0)], (None, 2))
nt.assert_array_equal(m, np.array([[0, 0], [1, 1], [2, 0]]))

# a tuple of lists, fully specified shape
m = getmatrix(([1, 2], [3, 4]), (2, 2))
nt.assert_array_equal(m, np.array([[1, 2], [3, 4]]))

# the shape is checked, not reshaped
with self.assertRaises(ValueError):
getmatrix([[0, 1, 2], [0, 1, 0]], (3, None))
with self.assertRaises(ValueError):
getmatrix([[0, 0], [1, 1], [2, 0]], (2, None))

# a range is a 1D sequence of numbers
m = getmatrix(range(4), (2, 2))
nt.assert_array_equal(m, np.array([[0, 1], [2, 3]]))

def test_verifymatrix(self):
with self.assertRaises(TypeError):
assertmatrix(3)
Expand Down Expand Up @@ -237,6 +262,20 @@ def test_homogeneous_conversion_unsupported_array_shapes(self):
with self.assertRaises(ValueError):
convert(np.ones(shape))

def test_getvector_range(self):
# a range is a sequence of numbers (issue #255)
v = getvector(range(1, 7))
self.assertIsInstance(v, np.ndarray)
nt.assert_array_equal(v, np.r_[1, 2, 3, 4, 5, 6])

v = getvector(range(3), 3, out="list")
self.assertEqual(v, [0, 1, 2])

v = getvector(range(3), out="col")
nt.assert_equal(v.shape, (3, 1))

nt.assert_raises(ValueError, getvector, range(3), 4)

def test_getvector(self):
l = [1, 2, 3]
t = (1, 2, 3)
Expand Down