[sage-support] Re: multiply a list by a constant
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
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
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
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
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
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
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
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
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
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
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
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 -~--~~~~--~~--~--~---