Den 03.04.2011 04:17, skrev Arthur de Souza Ribeiro:

static PyMethodDef cmath_methods[] = {
    {"acos",   cmath_acos,  METH_VARARGS, c_acos_doc},
    {"acosh",  cmath_acosh, METH_VARARGS, c_acosh_doc},
    {"asin",   cmath_asin,  METH_VARARGS, c_asin_doc},
    {"asinh",  cmath_asinh, METH_VARARGS, c_asinh_doc},
    {"atan",   cmath_atan,  METH_VARARGS, c_atan_doc},
    {"atanh",  cmath_atanh, METH_VARARGS, c_atanh_doc},
    {"cos",    cmath_cos,   METH_VARARGS, c_cos_doc},
    {"cosh",   cmath_cosh,  METH_VARARGS, c_cosh_doc},
    {"exp",    cmath_exp,   METH_VARARGS, c_exp_doc},
    {"isfinite", cmath_isfinite, METH_VARARGS, cmath_isfinite_doc},
    {"isinf",  cmath_isinf, METH_VARARGS, cmath_isinf_doc},
    {"isnan",  cmath_isnan, METH_VARARGS, cmath_isnan_doc},
    {"log",    cmath_log,   METH_VARARGS, cmath_log_doc},
    {"log10",  cmath_log10, METH_VARARGS, c_log10_doc},
    {"phase",  cmath_phase, METH_VARARGS, cmath_phase_doc},
    {"polar",  cmath_polar, METH_VARARGS, cmath_polar_doc},
    {"rect",   cmath_rect,  METH_VARARGS, cmath_rect_doc},
    {"sin",    cmath_sin,   METH_VARARGS, c_sin_doc},
    {"sinh",   cmath_sinh,  METH_VARARGS, c_sinh_doc},
    {"sqrt",   cmath_sqrt,  METH_VARARGS, c_sqrt_doc},
    {"tan",    cmath_tan,   METH_VARARGS, c_tan_doc},
    {"tanh",   cmath_tanh,  METH_VARARGS, c_tanh_doc},
    {NULL,              NULL}           /* sentinel */
};


static struct PyModuleDef cmathmodule = {
    PyModuleDef_HEAD_INIT,
    "cmath",
    module_doc,
    -1,
    cmath_methods,
    NULL,
    NULL,
    NULL,
    NULL
};


Cython will make this, do not care about it. You don't have to set up jump tables to make Python get the right function from Cython generated C code. If you have 22 Python-callable functions (i.e. declared def or cpdef), Cython will make a jump table for those as above.



Another stuff that I'm getting in trouble in this initial part is how we would translate functions like PyArg_ParseTuple, any clue? I'm studing ways to replace too.


Do not care about PyArg_ParseTuple either. It's what C Python needs to parse function call arguments from a tuple into C primitives. Cython will do this, which is some of the raison d'etre for using Cython.

Also observe that any initialisation done in PyInit_cmathshould go as a module level function call in Cython, i.e. PyInit_cmathis called on import just like module level Python and Cython code.

I don't have time to implement all of cmathmodule.c, but here is a starter (not tested & not complete).

It might actually be that we should use "cdef complex z" instead of "cdef double complex z". There might be a distinction in the generated C/C++ code between those types, e.g. Py_complex for complex and "double _Complex" or "std::complex<double>" for double complex, even though they are binary equivalent. I'm not sure about the state of Cython with respect to complex numbers, so just try it and see which works better :-)

Also observe that we do not release the GIL here. That is not because these functions are not thread-safe, they are, but yielding the GIL will slow things terribly.

Sturla





cimport math
cimport stdlib


cdef extern from "_math.h":
    int Py_IS_FINITE(double)
    int Py_IS_NAN(double)
    double copysign(double,double)


cdef enum special_types:
    ST_NINF  # 0, negative infinity
    ST_NEG   # 1, negative finite number (nonzero)
    ST_NZERO # 2, -0.
    ST_PZERO # 3, +0.
    ST_POS   # 4, positive finite number (nonzero)
    ST_PINF  # 5, positive infinity
    ST_NAN   # 6, Not a Number


cdef inline special_types special_type(double d):
    if (Py_IS_FINITE(d)):
        if (d != 0):
            if (copysign(1., d) == 1.):
                return ST_POS
            else
                return ST_NEG
        else:
            if (copysign(1., d) == 1.):
                return ST_PZERO
            else
                return ST_NZERO
    if (Py_IS_NAN(d)):
        return ST_NAN
    if (copysign(1., d) == 1.):
        return ST_PINF
    else:
        return ST_NINF


cdef void INIT_SPECIAL_VALUES( double complex *table,
                               double complex arc[][7]):
    stdlib.memcpy(table, &(src[0][0]), 7*7*sizeof(double complex))



cdef inline double complex *SPECIAL_VALUE(double complex z, double complex table[][7]):
    if (not Py_IS_FINITE(z.real)) or (not Py_IS_FINITE(z.imag)):
        errno = 0
        return &(table[special_type(z.real)][special_type(z.imag)])
    else:
        return NULL



cdef double complex acosh_special_values[7][7]

INIT_SPECIAL_VALUES( acos_special_values, {
 C(P34,INF) C(P,INF) C(P,INF) C(P,-INF) C(P,-INF) C(P34,-INF) C(N,INF)
 C(P12,INF) C(U,U) C(U,U) C(U,U) C(U,U) C(P12,-INF) C(N,N)
 C(P12,INF) C(U,U) C(P12,0.) C(P12,-0.) C(U,U) C(P12,-INF) C(P12,N)
 C(P12,INF) C(U,U) C(P12,0.) C(P12,-0.) C(U,U) C(P12,-INF) C(P12,N)
 C(P12,INF) C(U,U) C(U,U) C(U,U) C(U,U) C(P12,-INF) C(N,N)
 C(P14,INF) C(0.,INF) C(0.,INF) C(0.,-INF) C(0.,-INF) C(P14,-INF) C(N,INF)
 C(N,INF) C(N,N) C(N,N) C(N,N) C(N,N) C(N,-INF) C(N,N)
 })



cdef double complex cmath_acosh(double complex z):

    cdef double complex s1, s2, r, *psv

    psv = SPECIAL_VALUE(z, acosh_special_values)
    if (psv != NULL):
        return psv[0]

if (math.fabs(z.real) > CM_LARGE_DOUBLE or math.fabs(z.imag) > CM_LARGE_DOUBLE):
        # avoid unnecessary overflow for large arguments
        r.real = math.log(hypot(z.real/2., z.imag/2.)) + M_LN2*2.
        r.imag = math.atan2(z.imag, z.real)
    else:
        s1.real = z.real - 1.
        s1.imag = z.imag
s1 = cmath_sqrt(s1) # cdef double complex cmath_sqrt(double complex z)
        s2.real = z.real + 1.
        s2.imag = z.imag
        s2 = cmath_sqrt(s2)
        r.real = math.asinh(s1.real*s2.real + s1.imag*s2.imag)
        r.imag = 2.*math.atan2(s1.imag, s2.real)
    errno = 0
    return r


def acosh(object arg):
    """acos(x)

Return the arc cosine of x."""
    double complex z
    z = cmath_acosh(<double complex> arg)
    return complex(z)




























_______________________________________________
cython-devel mailing list
cython-devel@python.org
http://mail.python.org/mailman/listinfo/cython-devel

Reply via email to