📄 statc.cpp
字号:
\
PyErr_Clear(); \
\
vector<PyWrapper> wlist; \
if (PyList2wlist(pylist, wlist)) \
PyWrapper res1, res2; \
res1=name(wlist, mom, res2); \
return PyBuildValue("OO", (PyObject *)res1, (PyObject *)res2); \
} \
PYERROR(PyExc_AttributeError, #name": invalid arguments", PYNULL); \
PyCATCH \
}
#define T_T_FROM_LIST_INT(name) T_T_FROM_LIST_plus(name, int, "Oi")
#define T_T_FROM_LIST_DOUBLE(name) T_T_FROM_LIST_plus(name, double, "Od")
#define DOUBLE_DOUBLE_FROM_LIST_plus(name, type, pys) \
PyObject *py_##name(PyObject *, PyObject *args) \
{ PyTRY \
PyObject *pylist; \
double res1, res2; \
type mom; \
if ( PyArg_ParseTuple(args, pys, &pylist, &mom)) {\
vector<double> flist; \
if (PyList2flist(pylist, flist)) \
res1=name(flist, mom, res2); \
\
PyErr_Clear(); \
\
vector<PyWrapper> wlist; \
if (PyList2wlist(pylist, wlist)) \
res1=name(wlist, mom, res2); \
\
else PYERROR(PyExc_AttributeError, #name": invalid arguments", PYNULL); \
\
return PyBuildValue("dd", res1, res2); \
} \
PYERROR(PyExc_AttributeError, #name": invalid arguments", PYNULL); \
PyCATCH \
}
#define DOUBLE_DOUBLE_FROM_LIST_INT(name) DOUBLE_DOUBLE_FROM_LIST_plus(name, int, "Oi")
#define DOUBLE_DOUBLE_FROM_LIST_DOUBLE(name) DOUBLE_DOUBLE_FROM_LIST_plus(name, double, "Od")
#define T_T_FROM_LIST_T(name) \
PyObject *py_##name(PyObject *, PyObject *args) \
{ PyTRY \
PyObject *pylist; \
double mom; \
vector<double> flist; \
if ( PyArg_ParseTuple(args, "Od", &pylist, &mom)\
&& (PyList2flist(pylist, flist))) {\
double res1, res2; \
res1=name(flist, mom, res2); \
return Py_BuildValue("dd", res1, res2); \
} \
\
PyErr_Clear(); \
\
PyObject *wmom; \
vector<PyWrapper> wlist; \
if ( PyArg_ParseTuple(args, "OO", &pylist, &wmom)\
&& (PyList2wlist(pylist, wlist))) {\
PyWrapper res1, res2; \
res1=name(wlist, PyWrapper(mom), res2); \
return Py_BuildValue("NN", (PyObject *)res1, (PyObject *)res2); \
} \
PYERROR(PyExc_AttributeError, #name": invalid arguments", PYNULL); \
PyCATCH \
}
#define T_FROM_T(name) \
PyObject *py_##name(PyObject *, PyObject *args) \
{ PyTRY \
double x; \
if (PyArg_ParseTuple(args, "d", &x)) \
return PyFloat_FromDouble(name(x)); \
\
PyErr_Clear(); \
\
PyObject *pyx; \
if (PyArg_ParseTuple(args, "O", &pyx)) \
return (PyObject *)(name(PyWrapper(pyx))); \
\
return PYNULL; \
PyCATCH \
}
#define T_FROM_T_T_T(name) \
PyObject *py_##name(PyObject *, PyObject *args) \
{ PyTRY \
double x, y, z; \
if (PyArg_ParseTuple(args, "ddd", &x, &y, &z)) \
return PyFloat_FromDouble(name(x, y, z)); \
\
PyErr_Clear(); \
\
PyObject *pyx, *pyy, *pyz; \
if (PyArg_ParseTuple(args, "OOO", &pyx, &pyy, &pyz)) \
return (PyObject *)(name(PyWrapper(pyx), PyWrapper(pyy), PyWrapper(pyz))); \
\
return PYNULL; \
PyCATCH \
}
#define T_FROM_T_T(name) \
PyObject *py_##name(PyObject *, PyObject *args) \
{ PyTRY \
double x, y; \
if (PyArg_ParseTuple(args, "dd", &x, &y)) \
return PyFloat_FromDouble(name(x, y)); \
\
PyErr_Clear(); \
\
PyObject *pyx, *pyy; \
if (PyArg_ParseTuple(args, "OO", &pyx, &pyy)) \
return (PyObject *)(name(PyWrapper(pyx), PyWrapper(pyy))); \
\
return PYNULL; \
PyCATCH \
}
#define T_FROM_INT_INT_T(name) \
PyObject *py_##name(PyObject *, PyObject *args) \
{ PyTRY \
double x; \
int i1, i2; \
if (PyArg_ParseTuple(args, "iid", &i1, &i2, &x)) \
return PyFloat_FromDouble(name(i1, i2, x)); \
\
PyErr_Clear(); \
\
PyObject *pyx; \
if (PyArg_ParseTuple(args, "iiO", &i1, &i2, &pyx)) \
return (PyObject *)(name(i1, i2, PyWrapper(pyx))); \
\
return PYNULL; \
PyCATCH \
}
/* *********** AUXILIARY FUNCTIONS ************/
class Callback {
public:
PyObject *callback;
Callback(PyObject *cb)
: callback(cb)
{ if (cb)
if (cb==Py_None)
callback=PYNULL;
else {
if (!PyCallable_Check(cb))
throw StatException("Callback: non-callable callback function");
Py_XINCREF(callback);
}
}
~Callback()
{ Py_XDECREF(callback); }
Callback(const Callback &other)
: callback(other.callback)
{ Py_XINCREF(callback); }
void operator = (const Callback &other)
{ Py_XINCREF(other.callback);
Py_XDECREF(callback);
callback=other.callback;
}
};
class BoolUnaryCallback : public Callback {
public:
BoolUnaryCallback(PyObject *cb)
: Callback(cb)
{}
bool operator ()(const PyWrapper &x) const
{ if (!x.pyobject)
throw StatException("BoolUnaryCallable: invalid object");
PyObject *args=Py_BuildValue("(O)", x.pyobject);
PyObject *res=PyEval_CallObject(callback, args);
Py_DECREF(args);
PyWrapper::checkForError();
return PyObject_IsTrue(res)!=0;
}
};
class BoolBinaryCallback : public Callback {
public:
typedef PyWrapper first_argument_type;
typedef PyWrapper second_argument_type;
typedef bool result_type;
BoolBinaryCallback(PyObject *cb)
: Callback(cb)
{}
bool operator ()(const PyWrapper &x, const PyWrapper &y) const
{ if (!x.pyobject || !y.pyobject)
throw StatException("BoolBinaryCallable: invalid objects");
PyObject *args=Py_BuildValue("OO", x.pyobject, y.pyobject);
PyObject *res=PyEval_CallObject(callback, args);
Py_DECREF(args);
PyWrapper::checkForError();
return PyObject_IsTrue(res)!=0;
}
};
class IsTrueCallback : public BoolUnaryCallback {
public:
IsTrueCallback(PyObject *cb=NULL)
: BoolUnaryCallback(cb)
{}
bool operator()(const PyWrapper &x) const
{ if (!x.pyobject)
throw StatException("IsTrueCallback: invalid object");
return callback ? BoolUnaryCallback::operator ()(x) : (PyObject_IsTrue(x.pyobject)!=0);
}
};
class LessThanCallback : public BoolBinaryCallback {
public:
LessThanCallback(PyObject *o=NULL)
: BoolBinaryCallback(o)
{}
bool operator()(const PyWrapper &x, const PyWrapper &y) const
{ if (!x.pyobject || !y.pyobject)
throw StatException("CompareCallback: invalid objects");
return callback ? BoolBinaryCallback::operator ()(x, y) : (x<y);
}
};
/* *********** CENTRAL TENDENCY ************/
T_FROM_LIST(geometricmean)
T_FROM_LIST(harmonicmean)
T_FROM_LIST(mean)
PyObject *py_median(PyObject *, PyObject *args)
{ PyTRY
vector<double> flist;
if (args2flist(args, flist))
return PyFloat_FromDouble(median(flist));
PyErr_Clear();
vector<PyWrapper> wlist;
if (args2wlist(args, wlist))
return median(wlist);
PyErr_Clear();
PyObject *pylist, *pycomp=NULL;
if ( PyArg_ParseTuple(args, "O|O", &pylist, &pycomp)
|| !PyList_Check(pylist))
PYERROR(PyExc_AttributeError, "list expected", PYNULL)
if (!PyList2wlist(pylist, wlist))
return PYNULL;
return median(wlist, LessThanCallback(pycomp));
PyCATCH
}
PyObject *py_mode(PyObject *, PyObject *args)
{ PyTRY
vector<double> flist;
if (args2flist(args, flist)) {
vector<double> modes;
int res=mode(flist, modes);
return Py_BuildValue("iN", res, flist2PyList(modes));
}
PyErr_Clear();
PyObject *pylist, *pycomp=NULL;
vector<PyWrapper> wlist, modes;
if ( !PyArg_ParseTuple(args, "O|O", &pylist, &pycomp)
|| !PyList_Check(pylist))
PYERROR(PyExc_AttributeError, "mode: list and optional compare function expected", PYNULL)
if (!PyList2wlist(pylist, wlist))
return PYNULL;
int res= pycomp ? mode(wlist, modes, LessThanCallback(pycomp))
: mode(wlist, modes);
PYERROR(PyExc_SystemError, "mode: failed", PYNULL);
return Py_BuildValue("iN", res, wlist2PyList(modes));
PyCATCH
}
/* *********** MOMENTS ************/
T_FROM_LIST_INT(moment)
T_FROM_LIST(variation)
T_FROM_LIST(skewness)
T_FROM_LIST(kurtosis)
/* *********** FREQUENCY STATS************/
PyObject *py_scoreatpercentile(PyObject *, PyObject *args)
{ PyTRY
PyObject *pylist;
double perc;
vector<double> flist;
if ( PyArg_ParseTuple(args, "Od", &pylist, &perc)
&& PyList2flist(pylist, flist))
return PyFloat_FromDouble(scoreatpercentile(flist, perc));
PyErr_Clear();
vector<PyWrapper> wlist;
PyObject *pycomp=NULL;
if ( PyArg_ParseTuple(args, "Od|O", &pylist, &perc, &pycomp)
&& PyList2wlist(pylist, wlist))
return (PyObject *)(scoreatpercentile(wlist, perc, LessThanCallback(pycomp)));
PYERROR(PyExc_AttributeError, "scoreatpercentile: list, percentile and optional compare function expected", PYNULL);
PyCATCH
}
PyObject *py_percentileofscore(PyObject *, PyObject *args)
{ PyTRY
PyObject *pylist;
double score;
vector<double> flist;
if ( PyArg_ParseTuple(args, "Od", &pylist, &score)
&& PyList2flist(pylist, flist))
return PyFloat_FromDouble(percentileofscore(flist, score));
PyErr_Clear();
vector<PyWrapper> wlist;
PyObject *pyscore, *pycomp=NULL;
if ( PyArg_ParseTuple(args, "OO|O", &pylist, &pyscore, &pycomp)
&& PyList2wlist(pylist, wlist))
return PyFloat_FromDouble(percentileofscore(wlist, PyWrapper(pyscore), LessThanCallback(pycomp)));
PYERROR(PyExc_AttributeError, "percentileofscore: list, score and optional compare function expected", PYNULL);
PyCATCH
}
#define CALL_HISTOGRAM 0
#define CALL_CUMFREQ 1
#define CALL_RELFREQ 2
#define HISTOSWITCH(pars, parsd) \
switch (function) { \
case CALL_HISTOGRAM: histogram pars; break; \
case CALL_CUMFREQ: cumfreq pars; break; \
case CALL_RELFREQ: relfreq parsd; break; \
}
PyObject *py_histograms(PyObject *args, int function)
{ PyTRY
vector<int> counts;
vector<double> dcounts;
int extrapoints;
PyObject *pylist;
int numbins=10;
{
double min, binsize;
const double qNaN=numeric_limits<double>::quiet_NaN();
double defaultMin=qNaN, defaultMax=qNaN;
vector<double> flist;
if ( PyArg_ParseTuple(args, "O|idd", &pylist, &numbins, &defaultMin, &defaultMax)
&& PyList2flist(pylist, flist)) {
if ((defaultMin!=qNaN) && (defaultMax!=qNaN))
HISTOSWITCH((flist, counts, min, binsize, extrapoints, defaultMin, defaultMax, numbins),
(flist, dcounts, min, binsize, extrapoints, defaultMin, defaultMax, numbins))
else
HISTOSWITCH((flist, counts, min, binsize, extrapoints, numbins),
(flist, dcounts, min, binsize, extrapoints, numbins))
return Py_BuildValue("Nddi",
function==CALL_RELFREQ ? flist2PyList(dcounts) : ilist2PyList(counts),
min, binsize, extrapoints);
}
}
PyErr_Clear();
{
PyObject *pyMin=NULL, *pyMax=NULL;
vector<PyWrapper> wlist;
PyWrapper min, binsize;
if ( PyArg_ParseTuple(args, "O|iOO", &pylist, &numbins, &pyMin, &pyMax)
&& PyList2wlist(pylist, wlist)) {
if (pyMin && pyMax)
HISTOSWITCH((wlist, counts, min, binsize, extrapoints, PyWrapper(pyMin), PyWrapper(pyMax), numbins),
(wlist, dcounts, min, binsize, extrapoints, PyWrapper(pyMin), PyWrapper(pyMax), numbins))
else
HISTOSWITCH((wlist, counts, min, binsize, extrapoints, numbins),
(wlist, dcounts, min, binsize, extrapoints, numbins))
return Py_BuildValue("NNNi",
function==CALL_RELFREQ ? flist2PyList(dcounts) : ilist2PyList(counts),
(PyObject *)min, (PyObject *)binsize, extrapoints);
}
}
PYERROR(PyExc_TypeError, "histogram: invalid arguments", PYNULL);
PyCATCH
}
PyObject *py_histogram(PyObject *, PyObject *args)
{ return py_histograms(args, CALL_HISTOGRAM); }
PyObject *py_cumfreq(PyObject *, PyObject *args)
{ return py_histograms(args, CALL_CUMFREQ); }
PyObject *py_relfreq(PyObject *, PyObject *args)
{ return py_histograms(args, CALL_RELFREQ); }
/* *********** VARIABILITY ************/
T_FROM_LIST(samplevar)
T_FROM_LIST(samplestdev)
T_FROM_LIST(var)
T_FROM_LIST(stdev)
T_FROM_LIST(sterr)
T_FROM_LIST_T(z)
LIST_FROM_LIST(zs)
/* *********** TRIMMING FUNCTIONS ************/
LIST_FROM_LIST_DOUBLE(trimboth)
PyObject *py_trim1(PyObject *, PyObject *args) \
{ PyTRY
PyObject *pylist;
double mom;
char *which=NULL;
if ( PyArg_ParseTuple(args, "Od|s", &pylist, &mom, &which)) {
bool right;
if (!which || strcmp(which, "right")==0)
right=true;
else if (strcmp(which, "left")==0)
right=false;
else
PYERROR(PyExc_AttributeError, "trim1: invalid 'tail' argument", PYNULL);
vector<double> flist;
if (PyList2flist(pylist, flist)) {
vector<double> fres;
trim1(flist, mom, fres, right);
return flist2PyList(fres);
}
PyErr_Clear();
vector<PyWrapper> wlist;
if (PyList2wlist(pylist, wlist)) {
vector<PyWrapper> wres;
trim1(wlist, mom, wres, right);
return wlist2PyList(wres);
}
}
PYERROR(PyExc_AttributeError, "trim1: invalid arguments", PYNULL);
PyCATCH
}
/* *********** CORRELATION FUNCTIONS************/
T_T_FROM_LIST_LIST(pearsonr)
DOUBLE_DOUBLE_FROM_LIST_LIST(spearmanr)
DOUBLE_DOUBLE_FROM_LIST_LIST(pointbiserialr)
DOUBLE_DOUBLE_FROM_LIST_LIST(kendalltau)
PyObject *py_linregress(PyObject *, PyObject *args)
{ PyTRY
#define VARS r, slope, intercepr, probrs, sterrest
vector<double> x, y;
if (args22lists(args, x, y)) {
double VARS;
linregress(x, y, VARS);
return Py_BuildValue("ddddd", VARS);
}
PyErr_Clear();
vector<PyWrapper> wx, wy;
if (args22wlists(args, wx, wy)) {
PyWrapper VARS;
linregress(wx, wy, VARS);
return Py_BuildValue("NNNNN", (PyObject *)r, (PyObject *)slope, (PyObject *)intercepr, (PyObject *)probrs, (PyObject *)sterrest);
}
#undef VARS
PYERROR(PyExc_AttributeError, "linregress: two lists expected", PYNULL);
PyCATCH
}
/* *********** INFERENTIAL STATISTICS ************/
T_T_FROM_LIST_T(ttest_1samp)
T_T_FROM_LIST_LIST(ttest_ind)
T_T_FROM_LIST_LIST(ttest_rel)
PyObject *py_chisquare(PyObject *, PyObject *args)
{ PyTRY
PyObject *pylist1, *pylist2=PYNULL;
if (PyArg_ParseTuple(args, "O|O", &pylist1, &pylist2)) {
vector<double> x, y;
if ( PyList2flist(pylist1, x)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -