[sage-support] Re: multiply a list by a constant

2008-10-22 Thread Robert Bradshaw

On Oct 21, 2008, at 10:17 PM, pong wrote:

 Thanks to both Dan and William. However, Dan's result puzzled me.
 Aren't they suggested that the for loop is faster?

 Here is what I got:

 sage: timeit('list(2*vector([random() for j in range(10)]))')
 625 loops, best of 3: 332 µs per loop
 sage: timeit('[2*random() for j in range(10)]')
 125 loops, best of 3: 8.3 ms per loop

A more precise benchmark (ignoring vector/list creation) would  
probably be:

sage: L = [random() for j in range(10)]
sage: v = vector(L)
sage: timeit(2*v)
625 loops, best of 3: 1.76 µs per loop
sage: timeit([2*a for a in L])
25 loops, best of 3: 29.2 ms per loop

To explain your timings, note

sage: parent(random())
type 'float'
sage: parent(vector([random() for j in range(10)]))
Vector space of dimension 10 over Real Double Field
sage: parent(2)
Integer Ring

In your first loop, it's creating a RDF vector and then multiplying  
by 2 via

sage: cm = sage.structure.element.get_coercion_model()
sage: cm.explain(2, v)
Action discovered.
 Left scalar multiplication by Integer Ring on Vector space of  
dimension 10 over Real Double Field
Result lives in Vector space of dimension 10 over Real Double Field
Vector space of dimension 10 over Real Double Field

in other words, it turns 2 into an RDF, then multiplies every  
element (in fast compiled code) of the RDF vector. In the second  
case, it's having to re-discover the float-Integer operation each  
time (as the result is a float) which happens to be the worst-case  
scenario. Note with RDF rather than floats

sage: timeit([2*a for a in v])
625 loops, best of 3: 20.9 µs per loop

(still not the speed of  a vector-element multiply, but much better).  
There is a ticket or two related to improving this, e.g. #3938 and  
#2898.

 which suggested otherwise. Also how does timeit determine how many
 loops to perform in a test?

In my experience (haven't looked at the code) it keeps timing until  
it hits about a second, going by powers of 5.

 Also, instead of doing your own loops, you can use %timeit:

 sage: %timeit [2*random() for j in range(10)]
 10 loops, best of 3: 6.87 µs per loop
 sage: %timeit list(2*vector([random() for j in range(10)]))
 1 loops, best of 3: 112 µs per loop

Note that the 2 is not getting preparsed, and so one is doing python- 
int * python-float. Also, in the second example, the bulk of the time  
is in the conversion, not the multiply

sage: sage: %timeit list(2*vector([random() for j in range(10)]))
1 loops, best of 3: 173 µs per loop
sage: %timeit list(vector([random() for j in range(10)]))
1 loops, best of 3: 167 µs per loop

 Using list comprehensions is almost always a good choice in Sage/ 
 Python;
 as I understand (and as we see above), they're very well-optimized.

Yes, though using vectors can be faster too, and if one's list really  
is a vector than it can make much easier to read code than  
manipulating lists.

- Robert


--~--~-~--~~~---~--~~
To post to this group, send email to sage-support@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sage-support
URLs: http://www.sagemath.org
-~--~~~~--~~--~--~---



[sage-support] Re: multiply a list by a constant

2008-10-21 Thread Dan Drake
On Tue, 21 Oct 2008 at 07:50AM -0700, pong wrote:
 I wrote two list tests:
 
 def test1():
   for k in range(10^3):
 v=[2*random() for j in range(10)]
   else: pass
 
 def test2():
for k in range(10^3):
  v=list(2*vector([random() for j in range(10)]))
else: pass
 
 It turns out that
 time test1() gives around 8s CUP time while time test2() shows only
 0.35s CUP time is used. Wow!

Also, instead of doing your own loops, you can use %timeit:

sage: %timeit [2*random() for j in range(10)]
10 loops, best of 3: 6.87 µs per loop
sage: %timeit list(2*vector([random() for j in range(10)]))
1 loops, best of 3: 112 µs per loop

Using list comprehensions is almost always a good choice in Sage/Python;
as I understand (and as we see above), they're very well-optimized.

Dan

-- 
---  Dan Drake [EMAIL PROTECTED]
-  KAIST Department of Mathematical Sciences
---  http://mathsci.kaist.ac.kr/~drake


signature.asc
Description: Digital signature


[sage-support] Re: multiply a list by a constant

2008-10-21 Thread William Stein

On Tue, Oct 21, 2008 at 4:09 PM, Dan Drake [EMAIL PROTECTED] wrote:
 On Tue, 21 Oct 2008 at 07:50AM -0700, pong wrote:
 I wrote two list tests:

 def test1():
   for k in range(10^3):
 v=[2*random() for j in range(10)]
   else: pass

 def test2():
for k in range(10^3):
  v=list(2*vector([random() for j in range(10)]))
else: pass

 It turns out that
 time test1() gives around 8s CUP time while time test2() shows only
 0.35s CUP time is used. Wow!

 Also, instead of doing your own loops, you can use %timeit:

 sage: %timeit [2*random() for j in range(10)]
 10 loops, best of 3: 6.87 µs per loop
 sage: %timeit list(2*vector([random() for j in range(10)]))
 1 loops, best of 3: 112 µs per loop

 Using list comprehensions is almost always a good choice in Sage/Python;
 as I understand (and as we see above), they're very well-optimized.

I also added a command called timeit, so you can do

sage: timeit(' [2*random() for j in range(10)]')

this has the advantage that the input is preparsed using
the Sage preparser, so might give a slightly more accurate
result, and work in some cases where %timeit doesn't work.
For example,

sage: %timeit R.x = QQ[]

   File magic-timeit, line 6
 R.x = QQ[]
   ^
SyntaxError: invalid syntax

sage: timeit('R.x = QQ[]')
625 loops, best of 3: 287 µs per loop

It would be reasonable to argue that the fact that %timeit doesn't
preparse its input is a bug in Sage (actually IPython), and that it
should.  I've cc'd Fernando Perez (author of IPython) in case he has a
comment.

William

--~--~-~--~~~---~--~~
To post to this group, send email to sage-support@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sage-support
URLs: http://www.sagemath.org
-~--~~~~--~~--~--~---



[sage-support] Re: multiply a list by a constant

2008-10-21 Thread pong

Thanks to both Dan and William. However, Dan's result puzzled me.
Aren't they suggested that the for loop is faster?

Here is what I got:

sage: timeit('list(2*vector([random() for j in range(10)]))')
625 loops, best of 3: 332 µs per loop
sage: timeit('[2*random() for j in range(10)]')
125 loops, best of 3: 8.3 ms per loop

which suggested otherwise. Also how does timeit determine how many
loops to perform in a test?


On Oct 21, 4:09 pm, Dan Drake [EMAIL PROTECTED] wrote:
 On Tue, 21 Oct 2008 at 07:50AM -0700, pong wrote:
  I wrote two list tests:

  def test1():
        for k in range(10^3):
              v=[2*random() for j in range(10)]
        else: pass

  def test2():
         for k in range(10^3):
               v=list(2*vector([random() for j in range(10)]))
         else: pass

  It turns out that
  time test1() gives around 8s CUP time while time test2() shows only
  0.35s CUP time is used. Wow!

 Also, instead of doing your own loops, you can use %timeit:

 sage: %timeit [2*random() for j in range(10)]
 10 loops, best of 3: 6.87 µs per loop
 sage: %timeit list(2*vector([random() for j in range(10)]))
 1 loops, best of 3: 112 µs per loop

 Using list comprehensions is almost always a good choice in Sage/Python;
 as I understand (and as we see above), they're very well-optimized.

 Dan

 --
 ---  Dan Drake [EMAIL PROTECTED]
 -  KAIST Department of Mathematical Sciences
 ---  http://mathsci.kaist.ac.kr/~drake

  signature.asc
  1KViewDownload
--~--~-~--~~~---~--~~
To post to this group, send email to sage-support@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sage-support
URLs: http://www.sagemath.org
-~--~~~~--~~--~--~---



[sage-support] Re: multiply a list by a constant

2008-10-20 Thread pong

Thanks Marshall. I have thought about that as well.
Since I want to optimize time. I want to see if your method is faster
then a for loop. However, I run into something puzzling:

vector( [k for k in range(10)]) results in an error. Sage compliant
about

TypeError: unable to find a common ring for all elements

But if you check each element of the list, I got type 'int'

So why SAGE is complaining?

On Oct 19, 7:27 am, Marshall Hampton [EMAIL PROTECTED] wrote:
 Another option is to convert your list to a vector, and then convert
 it back.  This is more awkward for a single operation but if you are
 doing lots of vector addition and scalar multiplication it can be the
 way to go.
 I.e. you can do:

 sage: a = [3,4]
 sage: a = list(2*vector(a))
 sage: a
 [6, 8]

 -M. Hampton

 On Oct 19, 1:15 am, Robert Bradshaw [EMAIL PROTECTED]
 wrote:

  On Oct 18, 2008, at 10:14 PM, Alex Ghitza wrote:

   Hmmm.  As far as I know you can use _ as a placeholder for a
   variable, and it's meant for this kind of use (where you don't
   really want to introduce a new variable name).  It's strange that
   it doesn't work for you.  Can you post the error message that you get?

  Actually, _ is an actual variable, though personally I find it a bit
  harder to read than a normal letter. The one special thing about it
  (in ipython at least) is that it constantly gets reassigned to the
  last returned value, e.g.

  sage: 1+2
  3
  sage: _
  3

  - Robert
--~--~-~--~~~---~--~~
To post to this group, send email to sage-support@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sage-support
URLs: http://www.sagemath.org
-~--~~~~--~~--~--~---



[sage-support] Re: multiply a list by a constant

2008-10-20 Thread William Stein

On Mon, Oct 20, 2008 at 2:06 PM, pong [EMAIL PROTECTED] wrote:

 Thanks Marshall. I have thought about that as well.
 Since I want to optimize time. I want to see if your method is faster
 then a for loop. However, I run into something puzzling:

 vector( [k for k in range(10)]) results in an error. Sage compliant
 about

 TypeError: unable to find a common ring for all elements

I get

sage: vector( [k for k in range(10)])
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

Are you sure that's what you typed?


 But if you check each element of the list, I got type 'int'

 So why SAGE is complaining?

 On Oct 19, 7:27 am, Marshall Hampton [EMAIL PROTECTED] wrote:
 Another option is to convert your list to a vector, and then convert
 it back.  This is more awkward for a single operation but if you are
 doing lots of vector addition and scalar multiplication it can be the
 way to go.
 I.e. you can do:

 sage: a = [3,4]
 sage: a = list(2*vector(a))
 sage: a
 [6, 8]

 -M. Hampton

 On Oct 19, 1:15 am, Robert Bradshaw [EMAIL PROTECTED]
 wrote:

  On Oct 18, 2008, at 10:14 PM, Alex Ghitza wrote:

   Hmmm.  As far as I know you can use _ as a placeholder for a
   variable, and it's meant for this kind of use (where you don't
   really want to introduce a new variable name).  It's strange that
   it doesn't work for you.  Can you post the error message that you get?

  Actually, _ is an actual variable, though personally I find it a bit
  harder to read than a normal letter. The one special thing about it
  (in ipython at least) is that it constantly gets reassigned to the
  last returned value, e.g.

  sage: 1+2
  3
  sage: _
  3

  - Robert
 




-- 
William Stein
Associate Professor of Mathematics
University of Washington
http://wstein.org

--~--~-~--~~~---~--~~
To post to this group, send email to sage-support@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sage-support
URLs: http://www.sagemath.org
-~--~~~~--~~--~--~---



[sage-support] Re: multiply a list by a constant

2008-10-20 Thread pong

Yes, that's what I got. Maybe because I'm only using SAGE 3.1.1 or
there is something wrong with the installation.

sage: vector([k for k in range(10)])
---
TypeError Traceback (most recent call
last)

/home/pong/sage/ipython console in module()

/home/pong/sage/free_module_element.pyx in
sage.modules.free_module_element.vector (sage/modules/
free_module_element.c:2376)()

/home/pong/sage/free_module_element.pyx in
sage.modules.free_module_element.prepare (sage/modules/
free_module_element.c:2622)()

TypeError: unable to find a common ring for all elements


On Oct 20, 2:09 pm, William Stein [EMAIL PROTECTED] wrote:
 On Mon, Oct 20, 2008 at 2:06 PM, pong [EMAIL PROTECTED] wrote:

  Thanks Marshall. I have thought about that as well.
  Since I want to optimize time. I want to see if your method is faster
  then a for loop. However, I run into something puzzling:

  vector( [k for k in range(10)]) results in an error. Sage compliant
  about

  TypeError: unable to find a common ring for all elements

 I get

 sage: vector( [k for k in range(10)])
 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

 Are you sure that's what you typed?





  But if you check each element of the list, I got type 'int'

  So why SAGE is complaining?

  On Oct 19, 7:27 am, Marshall Hampton [EMAIL PROTECTED] wrote:
  Another option is to convert your list to a vector, and then convert
  it back.  This is more awkward for a single operation but if you are
  doing lots of vector addition and scalar multiplication it can be the
  way to go.
  I.e. you can do:

  sage: a = [3,4]
  sage: a = list(2*vector(a))
  sage: a
  [6, 8]

  -M. Hampton

  On Oct 19, 1:15 am, Robert Bradshaw [EMAIL PROTECTED]
  wrote:

   On Oct 18, 2008, at 10:14 PM, Alex Ghitza wrote:

Hmmm.  As far as I know you can use _ as a placeholder for a
variable, and it's meant for this kind of use (where you don't
really want to introduce a new variable name).  It's strange that
it doesn't work for you.  Can you post the error message that you get?

   Actually, _ is an actual variable, though personally I find it a bit
   harder to read than a normal letter. The one special thing about it
   (in ipython at least) is that it constantly gets reassigned to the
   last returned value, e.g.

   sage: 1+2
   3
   sage: _
   3

   - Robert

 --
 William Stein
 Associate Professor of Mathematics
 University of Washingtonhttp://wstein.org
--~--~-~--~~~---~--~~
To post to this group, send email to sage-support@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sage-support
URLs: http://www.sagemath.org
-~--~~~~--~~--~--~---



[sage-support] Re: multiply a list by a constant

2008-10-20 Thread William Stein

On Mon, Oct 20, 2008 at 2:24 PM, pong [EMAIL PROTECTED] wrote:

 Yes, that's what I got. Maybe because I'm only using SAGE 3.1.1 or
 there is something wrong with the installation.

I bet that's the case.  You should maybe upgrade.  We'll be posting
binaries soon.

William


 sage: vector([k for k in range(10)])
 ---
 TypeError Traceback (most recent call
 last)

 /home/pong/sage/ipython console in module()

 /home/pong/sage/free_module_element.pyx in
 sage.modules.free_module_element.vector (sage/modules/
 free_module_element.c:2376)()

 /home/pong/sage/free_module_element.pyx in
 sage.modules.free_module_element.prepare (sage/modules/
 free_module_element.c:2622)()

 TypeError: unable to find a common ring for all elements


 On Oct 20, 2:09 pm, William Stein [EMAIL PROTECTED] wrote:
 On Mon, Oct 20, 2008 at 2:06 PM, pong [EMAIL PROTECTED] wrote:

  Thanks Marshall. I have thought about that as well.
  Since I want to optimize time. I want to see if your method is faster
  then a for loop. However, I run into something puzzling:

  vector( [k for k in range(10)]) results in an error. Sage compliant
  about

  TypeError: unable to find a common ring for all elements

 I get

 sage: vector( [k for k in range(10)])
 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

 Are you sure that's what you typed?





  But if you check each element of the list, I got type 'int'

  So why SAGE is complaining?

  On Oct 19, 7:27 am, Marshall Hampton [EMAIL PROTECTED] wrote:
  Another option is to convert your list to a vector, and then convert
  it back.  This is more awkward for a single operation but if you are
  doing lots of vector addition and scalar multiplication it can be the
  way to go.
  I.e. you can do:

  sage: a = [3,4]
  sage: a = list(2*vector(a))
  sage: a
  [6, 8]

  -M. Hampton

  On Oct 19, 1:15 am, Robert Bradshaw [EMAIL PROTECTED]
  wrote:

   On Oct 18, 2008, at 10:14 PM, Alex Ghitza wrote:

Hmmm.  As far as I know you can use _ as a placeholder for a
variable, and it's meant for this kind of use (where you don't
really want to introduce a new variable name).  It's strange that
it doesn't work for you.  Can you post the error message that you get?

   Actually, _ is an actual variable, though personally I find it a bit
   harder to read than a normal letter. The one special thing about it
   (in ipython at least) is that it constantly gets reassigned to the
   last returned value, e.g.

   sage: 1+2
   3
   sage: _
   3

   - Robert

 --
 William Stein
 Associate Professor of Mathematics
 University of Washingtonhttp://wstein.org
 




-- 
William Stein
Associate Professor of Mathematics
University of Washington
http://wstein.org

--~--~-~--~~~---~--~~
To post to this group, send email to sage-support@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sage-support
URLs: http://www.sagemath.org
-~--~~~~--~~--~--~---



[sage-support] Re: multiply a list by a constant

2008-10-20 Thread Jason Grout

William Stein wrote:
 On Mon, Oct 20, 2008 at 2:06 PM, pong [EMAIL PROTECTED] wrote:
 Thanks Marshall. I have thought about that as well.
 Since I want to optimize time. I want to see if your method is faster
 then a for loop. However, I run into something puzzling:

 vector( [k for k in range(10)]) results in an error. Sage compliant
 about

 TypeError: unable to find a common ring for all elements
 
 I get
 
 sage: vector( [k for k in range(10)])
 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
 
 Are you sure that's what you typed?


It seems like this error was fixed recently.  Pong, what version of Sage 
are you running?

Jason


--~--~-~--~~~---~--~~
To post to this group, send email to sage-support@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sage-support
URLs: http://www.sagemath.org
-~--~~~~--~~--~--~---



[sage-support] Re: multiply a list by a constant

2008-10-19 Thread Robert Bradshaw

On Oct 18, 2008, at 10:14 PM, Alex Ghitza wrote:

 Hmmm.  As far as I know you can use _ as a placeholder for a  
 variable, and it's meant for this kind of use (where you don't  
 really want to introduce a new variable name).  It's strange that  
 it doesn't work for you.  Can you post the error message that you get?

Actually, _ is an actual variable, though personally I find it a bit  
harder to read than a normal letter. The one special thing about it  
(in ipython at least) is that it constantly gets reassigned to the  
last returned value, e.g.

sage: 1+2
3
sage: _
3

- Robert


--~--~-~--~~~---~--~~
To post to this group, send email to sage-support@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sage-support
URLs: http://www.sagemath.org
-~--~~~~--~~--~--~---



[sage-support] Re: multiply a list by a constant

2008-10-19 Thread Marshall Hampton

Another option is to convert your list to a vector, and then convert
it back.  This is more awkward for a single operation but if you are
doing lots of vector addition and scalar multiplication it can be the
way to go.
I.e. you can do:

sage: a = [3,4]
sage: a = list(2*vector(a))
sage: a
[6, 8]

-M. Hampton

On Oct 19, 1:15 am, Robert Bradshaw [EMAIL PROTECTED]
wrote:
 On Oct 18, 2008, at 10:14 PM, Alex Ghitza wrote:

  Hmmm.  As far as I know you can use _ as a placeholder for a
  variable, and it's meant for this kind of use (where you don't
  really want to introduce a new variable name).  It's strange that
  it doesn't work for you.  Can you post the error message that you get?

 Actually, _ is an actual variable, though personally I find it a bit
 harder to read than a normal letter. The one special thing about it
 (in ipython at least) is that it constantly gets reassigned to the
 last returned value, e.g.

 sage: 1+2
 3
 sage: _
 3

 - Robert
--~--~-~--~~~---~--~~
To post to this group, send email to sage-support@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sage-support
URLs: http://www.sagemath.org
-~--~~~~--~~--~--~---



[sage-support] Re: multiply a list by a constant

2008-10-18 Thread Alex Ghitza
Hmmm.  As far as I know you can use _ as a placeholder for a variable, and
it's meant for this kind of use (where you don't really want to introduce a
new variable name).  It's strange that it doesn't work for you.  Can you
post the error message that you get?

I guess it's not a big deal since you can always use x as you did, but if
it's really not working it might be a sign of other trouble.

Alex


On Sun, Oct 19, 2008 at 3:31 PM, pong [EMAIL PROTECTED] wrote:


 Hi Alex

Thanks for the quick reply. By _ you mean a variable? I tried your
 syntax but it does not work.
However, [2*x for x in [3,4]] does work.


-- 
Alex Ghitza -- Lecturer in Mathematics -- The University of Melbourne --
Australia -- http://www.ms.unimelb.edu.au/~aghitza/

--~--~-~--~~~---~--~~
To post to this group, send email to sage-support@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sage-support
URLs: http://www.sagemath.org
-~--~~~~--~~--~--~---