<br><br><div class="gmail_quote">On Thu, Sep 20, 2012 at 2:20 PM, Travis Oliphant <span dir="ltr"><<a href="mailto:travis@continuum.io" target="_blank">travis@continuum.io</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Here are a couple of scripts that might help (I used them to compare casting tables between various versions of NumPy):<br>
<br>
Casting Table Creation Script<br>
========================<br>
import numpy as np<br>
<br>
operators = np.set_numeric_ops().values()<br>
types = '?bhilqpBHILQPfdgFDGO'<br>
to_check = ['add', 'divide', 'minimum', 'maximum', 'remainder', 'true_divide', 'logical_or', 'bitwise_or', 'right_shift', 'less', 'equal']<br>

operators = [op for op in operators if op.__name__ in to_check]<br>
<br>
<br>
def type_wrap(op):<br>
    def func(obj1, obj2):<br>
        try:<br>
            result = op(obj1, obj2)<br>
            char = result.dtype.char<br>
        except:<br>
            char = 'X'<br>
        return char<br>
<br>
    return func<br>
<br>
def coerce():<br>
    result = {}<br>
    for op in operators:<br>
        d = {}<br>
        name = op.__name__<br>
        print name<br>
        op = type_wrap(op)<br>
        for type1 in types:<br>
            s1 = np.dtype(type1).type(2)<br>
            a1 = np.dtype(type1).type([1,2,3])<br>
            for type2 in types:<br>
                s2 = np.dtype(type2).type(1)<br>
                a2 = np.dtype(type2).type([2,3,4])<br>
                codes = []<br>
                # scalar <op> scalar<br>
                codes.append(op(s1, s2))<br>
                # scalar <op> array<br>
                codes.append(op(s1, a2))<br>
                # array <op> scalar<br>
                codes.append(op(a1, s2))<br>
                # array <op> array<br>
                codes.append(op(a1, a2))<br>
                d[type1,type2] = codes<br>
        result[name] = d<br>
<br>
        #for check_key in to_check:<br>
        # for key in result.keys():<br>
        #    if key == check_key:<br>
        #        continue<br>
        #    if result[key] == result[check_key]:<br>
        #        del result[key]<br>
        #assert set(result.keys()) == set(to_check)<br>
    return result<br>
<br>
import sys<br>
if sys.maxint > 2**33:<br>
    bits = 64<br>
else:<br>
    bits = 32<br>
<br>
def write():<br>
    import cPickle<br>
    file = open('coercion-%s-%sbit.pkl'%(np.__version__, bits),'w')<br>
    cPickle.dump(coerce(),file,protocol=2)<br>
    file.close()<br>
<br>
if __name__ == '__main__':<br>
    write()<br>
<br>
<br>
<br>
<br>
<br>
Comparison Script<br>
================<br>
<br>
import numpy as np<br>
<br>
<br>
def compare(result1, result2):<br>
    for op in result1.keys():<br>
        print "**** ", op, " ****"<br>
        if op not in result2:<br>
            print op, " not in the first"<br>
        table1 = result1[op]<br>
        table2 = result2[op]<br>
        if table1 == table2:<br>
            print "Tables are the same"<br>
        else:<br>
            if set(table1.keys()) != set(table2.keys()):<br>
                print "Keys are not the same"<br>
                continue<br>
            for key in table1.keys():<br>
                if table1[key] != table2[key]:<br>
                    print "Different at ", key, ": ", table1[key], table2[key]<br>
<br>
import cPickle<br>
import sys<br>
<br>
if __name__ == '__main__':<br>
    name1 = 'coercion-1.5.1-64bit.pkl'<br>
    name2 = 'coercion-1.6.1-64bit.pkl'<br>
<br>
    if len(sys.argv) > 1:<br>
        name1 = 'coercion-%s-64bit.pkl' % sys.argv[1]<br>
    if len(sys.argv) > 2:<br>
        name2 = 'coercion-%s-64bit.pkl' % sys.argv[2]<br>
    result1 = cPickle.load(open(name1))<br>
    result2 = cPickle.load(open(name2))<br>
    compare(result1, result2)<br>
<div class="HOEnZb"><div class="h5"><br>
<br>
<br>
On Sep 20, 2012, at 3:09 PM, Nathaniel Smith wrote:<br>
<br>
> On Mon, Sep 17, 2012 at 10:22 AM, Matthew Brett <<a href="mailto:matthew.brett@gmail.com">matthew.brett@gmail.com</a>> wrote:<br>
>> Hi,<br>
>><br>
>> On Sun, Sep 9, 2012 at 6:12 PM, Frédéric Bastien <<a href="mailto:nouiz@nouiz.org">nouiz@nouiz.org</a>> wrote:<br>
>>> The third is releated to change to the casting rules in numpy. Before<br>
>>> a scalar complex128 * vector float32 gived a vector of dtype<br>
>>> complex128. Now it give a vector of complex64. The reason is that now<br>
>>> the scalar of different category only change the category, not the<br>
>>> precision. I would consider a must that we warn clearly about this<br>
>>> interface change. Most people won't see it, but people that optimize<br>
>>> there code heavily could depend on such thing.<br>
>><br>
>> It seems to me that it would be a very good idea to put the casting<br>
>> table results into the tests to make sure we are keeping track of this<br>
>> kind of thing.<br>
>><br>
>> I'm happy to try to do it if no-one else more qualified has time.<br>
><br>
> I haven't seen any PRs show up from anyone else in the last few days,<br>
> and this would indeed be an excellent test to have, so that would be<br>
> awesome.<br>
><br></div></div></blockquote><div><br>IIRC, there are some scripts in the numpy repository. But I forget where I saw them.<br><br>Chuck <br></div><br></div>