Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #6638 > unrolled thread

Best way to compute length of arbitrary dimension vector?

Started byGabriel <snoopy.67.z@googlemail.com>
First post2011-05-30 02:11 -0700
Last post2011-06-01 12:35 -0700
Articles 10 — 6 participants

Back to article view | Back to comp.lang.python


Contents

  Best way to compute length of arbitrary dimension vector? Gabriel <snoopy.67.z@googlemail.com> - 2011-05-30 02:11 -0700
    Re: Best way to compute length of arbitrary dimension vector? Chris Rebert <clp2@rebertia.com> - 2011-05-30 02:24 -0700
    Re: Best way to compute length of arbitrary dimension vector? Peter Otten <__peter__@web.de> - 2011-05-30 11:46 +0200
      Re: Best way to compute length of arbitrary dimension vector? Gabriel <snoopy.67.z@googlemail.com> - 2011-05-30 06:38 -0700
        Re: Best way to compute length of arbitrary dimension vector? Ian Kelly <ian.g.kelly@gmail.com> - 2011-06-02 17:19 -0600
          Re: Best way to compute length of arbitrary dimension vector? Gabriel <snoopy.67.z@googlemail.com> - 2011-06-03 14:53 -0700
            Re: Best way to compute length of arbitrary dimension vector? Ian Kelly <ian.g.kelly@gmail.com> - 2011-06-03 16:17 -0600
            Re: Best way to compute length of arbitrary dimension vector? Robert Kern <robert.kern@gmail.com> - 2011-06-03 18:12 -0500
    Re: Best way to compute length of arbitrary dimension vector? "Gabriel Genellina" <gagsl-py2@yahoo.com.ar> - 2011-05-30 16:01 -0300
      Re: Best way to compute length of arbitrary dimension vector? Gabriel <snoopy.67.z@googlemail.com> - 2011-06-01 12:35 -0700

#6638 — Best way to compute length of arbitrary dimension vector?

FromGabriel <snoopy.67.z@googlemail.com>
Date2011-05-30 02:11 -0700
SubjectBest way to compute length of arbitrary dimension vector?
Message-ID<43d7a46e-3f48-4c11-a66b-a47a3d6b9b9d@k16g2000yqm.googlegroups.com>
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.

[toc] | [next] | [standalone]


#6644

FromChris Rebert <clp2@rebertia.com>
Date2011-05-30 02:24 -0700
Message-ID<mailman.2256.1306747466.9059.python-list@python.org>
In reply to#6638
On Mon, May 30, 2011 at 2:11 AM, Gabriel <snoopy.67.z@googlemail.com> 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

[toc] | [prev] | [next] | [standalone]


#6647

FromPeter Otten <__peter__@web.de>
Date2011-05-30 11:46 +0200
Message-ID<mailman.2258.1306749013.9059.python-list@python.org>
In reply to#6638
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

[toc] | [prev] | [next] | [standalone]


#6659

FromGabriel <snoopy.67.z@googlemail.com>
Date2011-05-30 06:38 -0700
Message-ID<a951396d-446b-4ad6-8ad3-d12420e251af@hg8g2000vbb.googlegroups.com>
In reply to#6647
Thanks a lot to both of you, Chris & Peter!

(I knew the solution would be simple ... ;-) )

[toc] | [prev] | [next] | [standalone]


#6896

FromIan Kelly <ian.g.kelly@gmail.com>
Date2011-06-02 17:19 -0600
Message-ID<mailman.2409.1307056774.9059.python-list@python.org>
In reply to#6659
On Thu, Jun 2, 2011 at 3:26 PM, Algis Kabaila <akabaila@pcug.org.au> 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

[toc] | [prev] | [next] | [standalone]


#6974

FromGabriel <snoopy.67.z@googlemail.com>
Date2011-06-03 14:53 -0700
Message-ID<c48d6e64-696a-4d4f-9099-c9137bf25fac@16g2000yqy.googlegroups.com>
In reply to#6896
> 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.

[toc] | [prev] | [next] | [standalone]


#6978

FromIan Kelly <ian.g.kelly@gmail.com>
Date2011-06-03 16:17 -0600
Message-ID<mailman.2441.1307139504.9059.python-list@python.org>
In reply to#6974
On Fri, Jun 3, 2011 at 3:53 PM, Gabriel <snoopy.67.z@googlemail.com> 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

[toc] | [prev] | [next] | [standalone]


#6980

FromRobert Kern <robert.kern@gmail.com>
Date2011-06-03 18:12 -0500
Message-ID<mailman.2443.1307142739.9059.python-list@python.org>
In reply to#6974
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

[toc] | [prev] | [next] | [standalone]


#6669

From"Gabriel Genellina" <gagsl-py2@yahoo.com.ar>
Date2011-05-30 16:01 -0300
Message-ID<mailman.2278.1306781932.9059.python-list@python.org>
In reply to#6638
En Mon, 30 May 2011 06:46:01 -0300, Peter Otten <__peter__@web.de>
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

[toc] | [prev] | [next] | [standalone]


#6820

FromGabriel <snoopy.67.z@googlemail.com>
Date2011-06-01 12:35 -0700
Message-ID<91447e94-4cbb-4358-9565-80d9a0cf90e3@j23g2000yqc.googlegroups.com>
In reply to#6669
> 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.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web