<br><br><div class="gmail_quote">On Thu, Jan 19, 2012 at 6:15 PM, Wes McKinney <span dir="ltr">&lt;<a href="mailto:wesmckinn@gmail.com">wesmckinn@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="HOEnZb"><div class="h5">On Thu, Jan 19, 2012 at 2:49 PM, Dmitrey &lt;<a href="mailto:dmitrey15@ukr.net">dmitrey15@ukr.net</a>&gt; wrote:<br>
&gt; On 01/19/2012 07:31 PM, Maciej Fijalkowski wrote:<br>
&gt;&gt;<br>
&gt;&gt; On Thu, Jan 19, 2012 at 6:46 PM, Dmitrey&lt;<a href="mailto:dmitrey15@ukr.net">dmitrey15@ukr.net</a>&gt;  wrote:<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; Hi all,<br>
&gt;&gt;&gt; could you provide clarification to numpypy new funcs accepting (not only<br>
&gt;&gt;&gt; for<br>
&gt;&gt;&gt; me, but for any other possible volunteers)?<br>
&gt;&gt;&gt; The doc I&#39;ve been directed says only &quot;You have to test exhaustively your<br>
&gt;&gt;&gt; module&quot;, while I would like to know more explicit rules.<br>
&gt;&gt;&gt; For example, &quot;at least 3 tests per func&quot; (however, I guess for funcs of<br>
&gt;&gt;&gt; different complexity and variability number of tests also should expected<br>
&gt;&gt;&gt; to<br>
&gt;&gt;&gt; be different).<br>
&gt;&gt;&gt; Also, are there any strict rules for the testcases to be submitted, or I,<br>
&gt;&gt;&gt; for example, can mere write<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; if __name__ == &#39;__main__&#39;:<br>
&gt;&gt;&gt;    assert array_equal(1, 1)<br>
&gt;&gt;&gt;    assert array_equal([1, 2], [1, 2])<br>
&gt;&gt;&gt;    assert array_equal(N.array([1, 2]), N.array([1, 2]))<br>
&gt;&gt;&gt;    assert array_equal([1, 2], N.array([1, 2]))<br>
&gt;&gt;&gt;    assert array_equal([1, 2], [1, 2, 3]) is False<br>
&gt;&gt;&gt;    print(&#39;passed&#39;)<br>
&gt;&gt;<br>
&gt;&gt; We have pretty exhaustive automated testing suites. Look for example<br>
&gt;&gt; in pypy/module/micronumpy/test directory for the test file style.<br>
&gt;&gt; They&#39;re run with py.test and we require at the very least full code<br>
&gt;&gt; coverage (every line has to be executed, there are tools to check,<br>
&gt;&gt; like coverage). Also passing &quot;unusual&quot; input, like sys.maxint  etc. is<br>
&gt;&gt; usually recommended. With your example, you would check if it works<br>
&gt;&gt; for say views and multidimensional arrays. Also &quot;is False&quot; is not<br>
&gt;&gt; considered good style.<br>
&gt;&gt;<br>
&gt;&gt;&gt; Or there is a certain rule for storing files with tests?<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; If I or someone else will submit a func with some tests like in the<br>
&gt;&gt;&gt; example<br>
&gt;&gt;&gt; above, will you put the func and tests in the proper files by yourself?<br>
&gt;&gt;&gt; I&#39;m<br>
&gt;&gt;&gt; not lazy to go for it by myself, but I mere no merged enough into numpypy<br>
&gt;&gt;&gt; dev process, including mercurial branches and numpypy files structure,<br>
&gt;&gt;&gt; and<br>
&gt;&gt;&gt; can spend only quite limited time for diving into it in nearest future.<br>
&gt;&gt;<br>
&gt;&gt; We generally require people to put their own tests as they go with the<br>
&gt;&gt; code (in appropriate places) because you also should not break<br>
&gt;&gt; anything. The usefullness of a patch that has to be sliced and diced<br>
&gt;&gt; and put into places is very limited and for straightforward<br>
&gt;&gt; mostly-copied code, like array_equal, plain useless, since it&#39;s almost<br>
&gt;&gt; as much work to just do it.<br>
&gt;<br>
&gt; Well, for this func (array_equal) my docstrings really were copied from<br>
&gt; cpython numpy (why wouln&#39;t do this to save some time, while license allows<br>
&gt; it?), but<br>
&gt; * why would&#39;n go for this (), while other programmers are busy by other<br>
&gt; tasks?<br>
&gt; * engines of my and CPython numpy funcs complitely differs. At first, in<br>
&gt; PyPy the CPython code just doesn&#39;t work at all (because of the problem with<br>
&gt; ndarray.flat). At 2nd, I have implemented walkaround - just replaced some<br>
&gt; code lines by<br>
&gt;    Size = a1.size<br>
&gt;    f1, f2 = a1.flat, a2.flat<br>
&gt;    # TODO: replace xrange by range in Python3<br>
&gt;    for i in xrange(Size):<br>
&gt;        if f1.next() != f2.next(): return False<br>
&gt;    return True<br>
&gt;<br>
&gt; Here are some results in CPython for the following bench:<br>
&gt;<br>
&gt; from time import time<br>
&gt; n = 100000<br>
&gt; m = 100<br>
&gt; a = N.zeros(n)<br>
&gt; b = N.ones(n)<br>
&gt; t = time()<br>
&gt; for i in range(m):<br>
&gt;    N.array_equal(a, b)<br>
&gt; print(&#39;classic numpy array_equal time elapsed (on different arrays): %0.5f&#39;<br>
&gt; % (time()-t))<br>
&gt;<br>
&gt;<br>
&gt; t = time()<br>
&gt; for i in range(m):<br>
&gt;    array_equal(a, b)<br>
&gt; print(&#39;Alternative array_equal time elapsed (on different arrays): %0.5f&#39; %<br>
&gt; (time()-t))<br>
&gt;<br>
&gt; b = N.zeros(n)<br>
&gt;<br>
&gt; t = time()<br>
&gt; for i in range(m):<br>
&gt;    N.array_equal(a, b)<br>
&gt; print(&#39;classic numpy array_equal time elapsed (on same arrays): %0.5f&#39; %<br>
&gt; (time()-t))<br>
&gt;<br>
&gt; t = time()<br>
&gt; for i in range(m):<br>
&gt;    array_equal(a, b)<br>
&gt; print(&#39;Alternative array_equal time elapsed (on same arrays): %0.5f&#39; %<br>
&gt; (time()-t))<br>
&gt;<br>
&gt; CPython numpy results:<br>
&gt; classic numpy array_equal time elapsed (on different arrays): 0.07728<br>
&gt; Alternative array_equal time elapsed (on different arrays): 0.00056<br>
&gt; classic numpy array_equal time elapsed (on same arrays): 0.11163<br>
&gt; Alternative array_equal time elapsed (on same arrays): 9.09458<br>
&gt;<br>
&gt; PyPy results (cannot test on &quot;classic&quot; version because it depends on some<br>
&gt; funcs that are unavailable yet):<br>
&gt; Alternative array_equal time elapsed (on different arrays): 0.00133<br>
&gt; Alternative array_equal time elapsed (on same arrays): 0.95038<br>
&gt;<br>
&gt;<br>
&gt; So, as you see, even in CPython numpy my version is 138 times faster for<br>
&gt; different arrays (yet slower in 90 times for same arrays). However, in real<br>
&gt; world usually different arrays come to this func, and only sometimes similar<br>
&gt; arrays are encountered.<br>
&gt; Well, for my implementation for case of equal arrays time elapsed<br>
&gt; essentially depends on their size, but in either way I still think my<br>
&gt; implementation is better than CPython, - it&#39;s faster and doesn&#39;t require<br>
&gt; allocation of memory for the boolean array, that will go to the logical_and.<br>
&gt;<br>
&gt; I updated my array_equal implementation with the changes mentioned above,<br>
&gt; some tests on multidimensional arrays you&#39;ve asked and put it in<br>
&gt; <a href="http://pastebin.com/tg2aHE6x" target="_blank">http://pastebin.com/tg2aHE6x</a> (now I&#39;ll update the <a href="http://bugs.pypy.org" target="_blank">bugs.pypy.org</a> entry with<br>
&gt; the link).<br>
&gt;<br>
&gt;<br>
&gt; -----------------------<br>
&gt; Regards, D.<br>
&gt; <a href="http://openopt.org/Dmitrey" target="_blank">http://openopt.org/Dmitrey</a><br>
&gt; _______________________________________________<br>
&gt; pypy-dev mailing list<br>
&gt; <a href="mailto:pypy-dev@python.org">pypy-dev@python.org</a><br>
&gt; <a href="http://mail.python.org/mailman/listinfo/pypy-dev" target="_blank">http://mail.python.org/mailman/listinfo/pypy-dev</a><br>
<br>
</div></div>Worth pointing out that the implementation of array_equal and<br>
array_equiv in NumPy are a bit embarrassing because they require a<br>
full N comparisons instead of short-circuiting whenever a False value<br>
is found. This is completely silly IMHO:<br>
<br>
In [34]: x = np.random.randn(100000)<br>
<br>
In [35]: y = np.random.randn(100000)<br>
<br>
In [36]: timeit np.array_equal(x, y)<br>
1000 loops, best of 3: 349 us per loop<br>
<span class="HOEnZb"><font color="#888888"><br>
- W<br>
</font></span><div class="HOEnZb"><div class="h5">_______________________________________________<br>
pypy-dev mailing list<br>
<a href="mailto:pypy-dev@python.org">pypy-dev@python.org</a><br>
<a href="http://mail.python.org/mailman/listinfo/pypy-dev" target="_blank">http://mail.python.org/mailman/listinfo/pypy-dev</a><br>
</div></div></blockquote></div><br>The correct solution (IMO), is to reuse the original NumPy implementation, but have logical_and.reduce short circuit correctly.  This has the nice side effect of allowing all() and any() to use logical_and/logical_or.reduce.<div>
<br></div><div>Alx<br clear="all"><div><br></div>-- <br>&quot;I disapprove of what you say, but I will defend to the death your right to say it.&quot; -- Evelyn Beatrice Hall (summarizing Voltaire)<br>&quot;The people&#39;s good is the highest law.&quot; -- Cicero<br>
<br>
</div>