Lawrence D'Oliveiro <l...@geek-central.gen.new_zealand> writes:

> Say a vector V is a tuple of 3 numbers, not all zero. You want to normalize 
> it (scale all components by the same factor) so its magnitude is 1.
>
> The usual way is something like this:
>
>     L = math.sqrt(V[0] * V[0] + V[1] * V[1] + V[2] * V[2])
>     V = (V[0] / L, V[1] / L, V[2] / L)
>
> What I don’t like is having that intermediate variable L leftover after the 
> computation.

Well, it also guarantees that the square root is computed once.

> Here’s how to do it in one step:
>
>     V = tuple \
>       ( x / math.sqrt
>                 (
>                   reduce(lambda a, b : a + b, (y * y for y in V), 0)
>                 )
>           for x in V
>       )
>
> which, incidentally, also works for vectors with dimensions other than 3.

And how many times does it call math.sqrt?

(That's actually not easy to test. Does any insider know the answer?
Does the compiler hoist the math.sqrt(...) out of the implicit loop? I
guess not, because it can't assert that reduce has no side effect.)

Your best bet is to define a function that does the normalization. Your
(local) name will disappear at the end of the call. If you want it to
work for any vector size:

def norm(V):
    L = math.sqrt( sum( [x**2 for x in V] ) )
    return [ x/L for x in V ]

If you do a lot of such computations, have a look at numpy.

-- Alain.
-- 
http://mail.python.org/mailman/listinfo/python-list

Reply via email to