Best way to compute length of arbitrary dimension vector?

Discussion in 'Python' started by Gabriel, May 30, 2011.

  1. Gabriel

    Gabriel Guest

    Well, the subject says it almost all: I'd like to write a small Vector
    class for arbitrary-dimensional vectors.

    I am wondering what would be the most efficient and/or most elegant
    way to compute the length of such a Vector?

    Right now, I've got

    def length(self): # x.length() = || x ||
    total = 0.0
    for k in range(len(self._coords)):
    d = self._coords[k]
    total += d*d
    return sqrt(total)

    However, that seems a bit awkward to me (at least in Python ;-) ).

    I know there is the reduce() function, but I can't seem to find a way
    to apply that to the case here (at least, not without jumping through
    too many hoops).

    I have also googled a bit, but found nothing really elegant.

    Any ideas?

    Best regards,
    Gabriel.
    Gabriel, May 30, 2011
    #1
    1. Advertising

  2. Gabriel

    Chris Rebert Guest

    On Mon, May 30, 2011 at 2:11 AM, Gabriel <> wrote:
    > Well, the subject says it almost all: I'd like to write a small Vector
    > class for arbitrary-dimensional vectors.
    >
    > I am wondering what would be the most efficient and/or most elegant
    > way to compute the length of such a Vector?
    >
    > Right now, I've got
    >
    >  def length(self):                                                                                     # x.length() = || x ||
    >    total = 0.0
    >    for k in range(len(self._coords)):
    >      d = self._coords[k]
    >      total += d*d
    >    return sqrt(total)
    >
    > However, that seems a bit awkward to me (at least in Python ;-) ).
    >
    > I know there is the reduce() function, but I can't seem to find a way
    > to apply that to the case here (at least, not without jumping through
    > too many hoops).
    >
    > I have also googled a bit, but found nothing really elegant.
    >
    > Any ideas?


    def length(self):
    return sqrt(sum(coord*coord for coord in self._coords))

    Cheers,
    Chris
    --
    http://rebertia.com
    Chris Rebert, May 30, 2011
    #2
    1. Advertising

  3. Gabriel

    Peter Otten Guest

    Gabriel wrote:

    > Well, the subject says it almost all: I'd like to write a small Vector
    > class for arbitrary-dimensional vectors.
    >
    > I am wondering what would be the most efficient and/or most elegant
    > way to compute the length of such a Vector?
    >
    > Right now, I've got
    >
    > def length(self): # x.length() = || x ||
    > total = 0.0
    > for k in range(len(self._coords)):
    > d = self._coords[k]
    > total += d*d
    > return sqrt(total)
    >
    > However, that seems a bit awkward to me (at least in Python ;-) ).
    >
    > I know there is the reduce() function, but I can't seem to find a way
    > to apply that to the case here (at least, not without jumping through
    > too many hoops).
    >
    > I have also googled a bit, but found nothing really elegant.


    >>> class Vector(object):

    .... def __init__(self, *coords):
    .... self._coords = coords
    .... def __abs__(self):
    .... return math.sqrt(sum(x*x for x in self._coords))
    ....
    >>> import math
    >>> abs(Vector(1,1))

    1.4142135623730951
    >>> abs(Vector(3,4))

    5.0
    Peter Otten, May 30, 2011
    #3
  4. Gabriel

    Gabriel Guest

    Thanks a lot to both of you, Chris & Peter!

    (I knew the solution would be simple ... ;-) )
    Gabriel, May 30, 2011
    #4
  5. En Mon, 30 May 2011 06:46:01 -0300, Peter Otten <>
    escribió:

    > Gabriel wrote:
    >
    >> Well, the subject says it almost all: I'd like to write a small Vector
    >> class for arbitrary-dimensional vectors.
    >>

    >
    >>>> class Vector(object):

    > ... def __init__(self, *coords):
    > ... self._coords = coords
    > ... def __abs__(self):
    > ... return math.sqrt(sum(x*x for x in self._coords))
    > ...
    >>>> import math
    >>>> abs(Vector(1,1))

    > 1.4142135623730951
    >>>> abs(Vector(3,4))

    > 5.0


    Using math.fsum instead of sum may improve accuracy, specially when
    len(coords)≫2

    py> import math
    py>
    py> def f1(*args):
    .... return math.sqrt(sum(x*x for x in args))
    ....
    py> def f2(*args):
    .... return math.sqrt(math.fsum(x*x for x in args))
    ....
    py> pi=math.pi
    py> args=[pi]*16
    py> abs(f1(*args)/4 - pi)
    4.4408920985006262e-16
    py> abs(f2(*args)/4 - pi)
    0.0


    --
    Gabriel Genellina
    Gabriel Genellina, May 30, 2011
    #5
  6. Gabriel

    Gabriel Guest

    > py> def f2(*args):
    > ...   return math.sqrt(math.fsum(x*x for x in args))


    Wow! Thanks a million - I didn't now about math.fsum!

    Best regards,
    Gabriel.
    Gabriel, Jun 1, 2011
    #6
  7. Gabriel

    Ian Kelly Guest

    On Thu, Jun 2, 2011 at 3:26 PM, Algis Kabaila <> wrote:
    > import math
    >
    > length = math.hypot(z, math.hypot(x, y))
    >
    > One line and fast.


    The dimension is arbitrary, though, so:

    length = reduce(math.hypot, self._coords, 0)

    Cheers,
    Ian
    Ian Kelly, Jun 3, 2011
    #7
  8. Gabriel

    Gabriel Guest


    > The dimension is arbitrary, though, so:
    >
    > length = reduce(math.hypot, self._coords, 0)
    >



    Thanks, I was going to ask Algis that same question.

    But still, is this solution really faster or better than the one using
    list comprehension and the expression 'x*x'?
    It seems to me that the above solution (using hypot) involves repeated
    square roots (with subsequent squaring).

    Best regards,
    Gabriel.
    Gabriel, Jun 3, 2011
    #8
  9. Gabriel

    Ian Kelly Guest

    On Fri, Jun 3, 2011 at 3:53 PM, Gabriel <> wrote:
    > But still, is this solution really faster or better than the one using
    > list comprehension and the expression 'x*x'?


    No, not really.

    >c:\python32\python -m timeit -s "coords = list(range(100))" -s "from math import hypot" -s "from functools import reduce" "reduce(hypot, coords, 0)"

    10000 loops, best of 3: 53.2 usec per loop

    >c:\python32\python -m timeit -s "coords = list(range(100))" -s "from math import sqrt, fsum" "sqrt(fsum(x*x for x in coords))"

    10000 loops, best of 3: 32 usec per loop

    >c:\python32\python -m timeit -s "coords = list(range(100))" -s "from math import sqrt" "sqrt(sum(x*x for x in coords))"

    100000 loops, best of 3: 14.4 usec per loop
    Ian Kelly, Jun 3, 2011
    #9
  10. Gabriel

    Robert Kern Guest

    On 6/3/11 4:53 PM, Gabriel wrote:
    >
    >> The dimension is arbitrary, though, so:
    >>
    >> length = reduce(math.hypot, self._coords, 0)
    >>

    >
    >
    > Thanks, I was going to ask Algis that same question.
    >
    > But still, is this solution really faster or better than the one using
    > list comprehension and the expression 'x*x'?
    > It seems to me that the above solution (using hypot) involves repeated
    > square roots (with subsequent squaring).


    It also means that the floating point numbers stay roughly the same size, so you
    will lose less precision as the number of elements goes up. I don't expect the
    number of elements will be large enough to matter, though.

    --
    Robert Kern

    "I have come to believe that the whole world is an enigma, a harmless enigma
    that is made terrible by our own mad attempt to interpret it as though it had
    an underlying truth."
    -- Umberto Eco
    Robert Kern, Jun 4, 2011
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Dimitri Ognibene

    arbitrary dimension array for math

    Dimitri Ognibene, Aug 8, 2006, in forum: Java
    Replies:
    7
    Views:
    1,038
    Stefan Ram
    Aug 8, 2006
  2. Replies:
    8
    Views:
    1,890
    Csaba
    Feb 18, 2006
  3. Luuk
    Replies:
    15
    Views:
    800
    Nobody
    Feb 11, 2010
  4. Replies:
    3
    Views:
    111
    Tad McClellan
    Mar 23, 2006
  5. PerlFAQ Server
    Replies:
    0
    Views:
    254
    PerlFAQ Server
    Feb 2, 2011
Loading...

Share This Page