[Cython] Fused Types

Dag Sverre Seljebotn d.s.seljebotn at astro.uio.no
Fri Apr 29 13:15:23 CEST 2011


On 04/29/2011 12:53 PM, mark florisson wrote:
> On 29 April 2011 12:28, Pauli Virtanen<pav at iki.fi>  wrote:
>> Fri, 29 Apr 2011 11:30:19 +0200, mark florisson wrote:
>>> On 29 April 2011 11:03, Pauli Virtanen<pav at iki.fi>  wrote:
>> [clip]
>>>> Are you planning to special-case the "real_t complex" syntax? Shooting
>>>> from the sidelines, one more generic solution might be, e.g.,
>>>
>>> I'm sorry, I'm not sure what syntax you are referring to. Are you
>>> talking about actual complex numbers?
>>
>> This:
>>
>> On 28 April 2011 23:30, Robert Bradshaw<robertwb at math.washington.edu>
>> wrote:
>>> OK, I take back what I said, I was looking at the RHS, not the LHS. If
>>> one needs to specialize in this manner, explicitly creating two
>>> branches should typically be enough. The same for casting. The one
>>> exception (perhaps) is "my_fused_type complex." Otherwise it's
>>> starting to feel too much like C++ template magic and complexity for
>>> little additional benefit.
>>
>> That is, declaring a complex type matching a real one.
>
> Ah, I see what you mean now.
>
>>>>         ctypedef cython.fused_type(A, B) struct_t
>>>>         ctypedef cython.fused_type(float, double, paired=struct_t) real_t
>>>>         ctypedef cython.fused_type(int_t, string_t, paired=struct_t) var_t
>>>>
>>>> and just restrict the specialization to cases that make sense.
>>>
>>> The paired means you're declaring types of attributes?
>>
>> No, just that real_t is specialized to float whenever struct_t is specialized
>> to A and to double when B. Or a more realistic example,
>>
>>         ctypedef cython.fused_type(float, double) real_t
>>         ctypedef cython.fused_type(float complex, double complex) complex_t
>>
>>         cdef real_plus_one(complex_t a):
>>             real_t b = a.real
>>             return b + 1
>>
>> which I suppose would not be a very unusual thing in numerical codes.

Did you mean

ctypedef cython.fused_type(float complex, double complex,
                            paired=real_t) complex_t

?

>> This would also allow writing the case you had earlier as
>>
>>         cdef cython.fused_type(string_t, int, paired=struct_t) attr_t
>>
>>         cdef func(struct_t mystruct, int i):
>>             cdef attr_t var
>>
>>             if typeof(mystruct) is typeof(int):
>>                 var = mystruct.attrib + i
>>                 ...
>>             else:
>>                 var = mystruct.attrib + i
>>                 ...
>>
>> Things would need to be done explicitly instead of implicitly, though,
>> but it would remove the need for any special handling of
>> the "complex" keyword.
>
> I see, so it's like a mapping. So, I didn't realize that you can't do this:
>
> def func(arbitrary_type complex x):
>      ...
>

We could support this, but I don't think it is powerful enough. I see 
some code that require pairings like this:

ctypedef cython.fused_type(float, double, float complex, \
  double complex) complex_or_float_t

ctypedef cython.fused_type(float, double, float, \
  double) only_float_t


cdef func(complex_or_float_t x):
     cdef only_float_t y
     ...

So IIUC, one could here add "paired=complex_or_float_t" to say that 
only_float_t links positionally to corresponding types in 
complex_or_float_t.

Perhaps "pair_up_with="? "given_by="?

Anyway, I'm wondering if the special case of complex could be handled by 
having magical built-in fused types for the floating point for these 
purposes, and that these would suffice *shrug*.

Dag Sverre


More information about the cython-devel mailing list