|
17 | 17 |
|
18 | 18 | try: # pragma: no cover |
19 | 19 | # print('Using SymPy') |
20 | | - from sympy import Matrix |
| 20 | + import sympy |
21 | 21 |
|
22 | 22 | _symbolics = True |
23 | 23 |
|
@@ -122,16 +122,82 @@ def norm(v): |
122 | 122 | >>> from spatialmath.base import * |
123 | 123 | >>> norm([3, 4]) |
124 | 124 |
|
| 125 | + .. note:: This function does not use NumPy, it is ~2x faster than |
| 126 | + `numpy.linalg.norm()` for a 3-vector |
| 127 | +
|
125 | 128 | :seealso: :func:`~spatialmath.base.unit` |
126 | 129 |
|
127 | 130 | :SymPy: supported |
128 | 131 | """ |
129 | | - v = getvector(v) |
130 | | - if v.dtype.kind == 'O': |
131 | | - return Matrix(v).norm() |
| 132 | + sum = 0 |
| 133 | + for x in v: |
| 134 | + sum += x * x |
| 135 | + |
| 136 | + if isinstance(sum, sympy.Expr): |
| 137 | + return sympy.sqrt(sum) |
132 | 138 | else: |
133 | | - return np.linalg.norm(v) |
| 139 | + return math.sqrt(sum) |
| 140 | + |
| 141 | +def normsq(v): |
| 142 | + """ |
| 143 | + Squared norm of vector |
| 144 | +
|
| 145 | + :param v: any vector |
| 146 | + :type v: array_like(n) |
| 147 | + :return: norm of vector |
| 148 | + :rtype: float |
134 | 149 |
|
| 150 | + ``norm(sq)`` is the sum of squared elements of the vector ``v`` |
| 151 | + or :math:`|v|^2`. |
| 152 | +
|
| 153 | + .. runblock:: pycon |
| 154 | +
|
| 155 | + >>> from spatialmath.base import * |
| 156 | + >>> normsq([2, 3]) |
| 157 | +
|
| 158 | + .. note:: This function does not use NumPy, it is ~2x faster than |
| 159 | + `numpy.linalg.norm() ** 2` for a 3-vector |
| 160 | +
|
| 161 | + :seealso: :func:`~spatialmath.base.unit` |
| 162 | +
|
| 163 | + :SymPy: supported |
| 164 | + """ |
| 165 | + sum = 0 |
| 166 | + for x in v: |
| 167 | + sum += x * x |
| 168 | + |
| 169 | + return sum |
| 170 | + |
| 171 | +def cross(u, v): |
| 172 | + """ |
| 173 | + Cross product of vectors |
| 174 | +
|
| 175 | + :param u: any vector |
| 176 | + :type u: array_like(3) |
| 177 | + :param v: any vector |
| 178 | + :type v: array_like(3) |
| 179 | + :return: cross product |
| 180 | + :rtype: nd.array(3) |
| 181 | +
|
| 182 | + ``cross(u, v)`` is the cross product of the vectors ``u`` and ``v``. |
| 183 | +
|
| 184 | + .. runblock:: pycon |
| 185 | +
|
| 186 | + >>> from spatialmath.base import * |
| 187 | + >>> cross([1, 0, 0], [0, 1, 0]) |
| 188 | +
|
| 189 | + .. note:: This function does not use NumPy, it is ~1.5x faster than |
| 190 | + `numpy.cross()` |
| 191 | +
|
| 192 | + :seealso: :func:`~spatialmath.base.unit` |
| 193 | +
|
| 194 | + :SymPy: supported |
| 195 | + """ |
| 196 | + return np.r_[ |
| 197 | + u[1] * v[2] - u[2] * v[1], |
| 198 | + u[2] * v[0] - u[0] * v[2], |
| 199 | + u[0] * v[1] - u[1] * v[0] |
| 200 | + ] |
135 | 201 |
|
136 | 202 | def isunitvec(v, tol=10): |
137 | 203 | """ |
@@ -277,9 +343,9 @@ def unittwist(S, tol=10): |
277 | 343 | Returns None if the twist has zero magnitude |
278 | 344 | """ |
279 | 345 |
|
280 | | - s = getvector(S, 6) |
| 346 | + S = getvector(S, 6) |
281 | 347 |
|
282 | | - if iszerovec(s, tol=tol): |
| 348 | + if iszerovec(S, tol=tol): |
283 | 349 | return None |
284 | 350 |
|
285 | 351 | v = S[0:3] |
@@ -322,9 +388,9 @@ def unittwist_norm(S, tol=10): |
322 | 388 | .. note:: Returns (None,None) if the twist has zero magnitude |
323 | 389 | """ |
324 | 390 |
|
325 | | - s = getvector(S, 6) |
| 391 | + S = getvector(S, 6) |
326 | 392 |
|
327 | | - if iszerovec(s, tol=tol): |
| 393 | + if iszerovec(S, tol=tol): |
328 | 394 | return (None, None) |
329 | 395 |
|
330 | 396 | v = S[0:3] |
@@ -460,4 +526,4 @@ def removesmall(v, tol=100): |
460 | 526 | if __name__ == '__main__': # pragma: no cover |
461 | 527 | import pathlib |
462 | 528 |
|
463 | | - exec(open(pathlib.Path(__file__).parent.absolute() / "test_vectors.py").read()) # pylint: disable=exec-used |
| 529 | + exec(open(pathlib.Path(__file__).parent.absolute() / "test" / "test_vectors.py").read()) # pylint: disable=exec-used |
0 commit comments