[Scipy-svn] r2526 - trunk/Lib/sandbox/timeseries/src
scipy-svn at scipy.org
scipy-svn at scipy.org
Wed Jan 10 13:13:52 CST 2007
Author: mattknox_ca
Date: 2007-01-10 13:13:48 -0600 (Wed, 10 Jan 2007)
New Revision: 2526
Modified:
trunk/Lib/sandbox/timeseries/src/cseries.c
Log:
major overhaul
Modified: trunk/Lib/sandbox/timeseries/src/cseries.c
===================================================================
--- trunk/Lib/sandbox/timeseries/src/cseries.c 2007-01-10 19:13:21 UTC (rev 2525)
+++ trunk/Lib/sandbox/timeseries/src/cseries.c 2007-01-10 19:13:48 UTC (rev 2526)
@@ -9,517 +9,616 @@
///////////////////////////////////////////////////////////////////////
+// helpers for frequency conversion routines //
-static //PyArrayObject *
-setArrayItem_1D(PyArrayObject **theArray, long index, PyObject *newVal)
-{
- if (index >= 0)
- {
- //set value in array
- PyArray_SETITEM(*theArray, PyArray_GetPtr(*theArray, &index), newVal);
+static long DtoB_weekday(long fromDate) { return (((fromDate / 7) * 5) + fromDate%7); }
+
+static long DtoB_WeekendToMonday(mxDateTimeObject *dailyDate) {
+
+ long absdate = dailyDate->absdate;
+ if (dailyDate->day_of_week > 4) {
+ //change to Monday after weekend
+ absdate += (7 - dailyDate->day_of_week);
}
-
+ return DtoB_weekday(absdate);
}
-static //PyArrayObject *
-setArrayItem_2D(PyArrayObject **theArray, long index_x, long index_y, PyObject *newVal)
-{
- long idx[] = {index_x, index_y};
+static long DtoB_WeekendToFriday(mxDateTimeObject *dailyDate) {
- if (index_x >= 0 && index_y >= 0) {
- //set value in array
- PyArray_SETITEM(*theArray, PyArray_GetPtr(*theArray, idx), newVal);
+ long absdate = dailyDate->absdate;
+ if (dailyDate->day_of_week > 4) {
+ //change to friday before weekend
+ absdate -= (dailyDate->day_of_week - 4);
}
+ return DtoB_weekday(absdate);
+}
+static long absdate_from_ymd(int y, int m, int d) {
+ mxDateTimeObject *tempDate;
+ long result;
+
+ tempDate = (mxDateTimeObject *)mxDateTime.DateTime_FromDateAndTime(y,m,d,0,0,0);
+ result = (long)(tempDate->absdate);
+ Py_DECREF(tempDate);
+ return result;
}
-static int
-freqVal(char freq)
-{
- switch(freq)
- {
- case 'A':
- //annual
- return 1;
- case 'Q':
- //quarterly
- return 2;
- case 'M':
- //monthly
- return 3;
- case 'B':
- //business
- return 4;
- case 'D':
- //daily
- return 5;
- default:
- return 0;
- }
+static mxDateTimeObject *day_before_mxobj(int y, int m, int d) {
+ return (mxDateTimeObject *)mxDateTime.DateTime_FromAbsDateAndTime(absdate_from_ymd(y, m, d) - 1, 0);
}
-static long
-toDaily(long fromDate, char fromFreq)
-{
- long absdate;
- int y,m,d;
+/*
+returns Date(y, m, d) converted to business frequency.
+If the initial result is a weekend, the following Monday is returned
+*/
+static long busday_before(int y, int m, int d) {
+ mxDateTimeObject *dailyDate;
+ long result;
- mxDateTimeObject *theDate;
+ dailyDate = (mxDateTimeObject *)mxDateTime.DateTime_FromDateAndTime(y,m,d,0,0,0);
+ result = DtoB_WeekendToMonday(dailyDate);
- //convert fromDate to days since (0 AD - 1 day)
- switch(fromFreq)
- {
- case 'D':
- absdate = fromDate;
- break;
- case 'B':
- absdate = ((fromDate-1)/5)*7 + (fromDate-1)%5 + 1;
- break;
- case 'M':
- y = fromDate/12;
- m = fromDate%12;
+ Py_DECREF(dailyDate);
+ return result;
+}
- if (m == 0)
- {
- m = 12;
- y--;
- }
- d=1;
- break;
- case 'Q':
- y = fromDate/4;
- m = (fromDate%4) * 3 - 2;
+/*
+returns Date(y, m, d) - 1 converted to business frequency.
+If the initial result is a weekend, the preceding Friday is returned
+*/
+static long busday_after(int y, int m, int d) {
+ mxDateTimeObject *dailyDate;
+ long result;
- if (m < 1)
- {
- m += 12;
- y--;
- }
- else if (m == 12)
- {
- m = 1;
- y++;
- }
- d=1;
- break;
- case 'A':
- y = fromDate;
- m = 1;
- d = 1;
- break;
- default:
- return -1;
- }
+ dailyDate = day_before_mxobj(y,m,d);
+ result = DtoB_WeekendToFriday(dailyDate);
- if (freqVal(fromFreq) < 4)
- {
- theDate = (mxDateTimeObject *)mxDateTime.DateTime_FromDateAndTime(y,m,d,0,0,0);
- absdate = (long)(theDate->absdate);
- }
+ Py_DECREF(dailyDate);
+ return result;
+}
- return absdate;
+///////////////////////////////////////////////
+// frequency specifc conversion routines
+// each function must take an integer fromDate and a char relation ('B' or 'A' for 'BEFORE' or 'AFTER')
+
+//************ FROM ANNUAL ***************
+
+static long asfreq_AtoQ(long fromDate, char relation) {
+ if (relation == 'B') { return fromDate * 4 + 1; }
+ else { return (fromDate + 1) * 4; }
}
+static long asfreq_AtoM(long fromDate, char relation) {
+ if (relation == 'B') { return fromDate * 12 + 1; }
+ else { return (fromDate + 1) * 12; }
+}
-static long
-getDateInfo_sub(long dateNum, char freq, char info) {
+static long asfreq_AtoW(long fromDate, char relation) { return 0; }
- long monthNum;
- mxDateTimeObject *convDate;
- convDate = (mxDateTimeObject *)mxDateTime.DateTime_FromAbsDateAndTime(toDaily(dateNum,freq),0);
+static long asfreq_AtoB(long fromDate, char relation) {
+ if (relation == 'B') { return busday_before(fromDate,1,1); }
+ else { return busday_after(fromDate+1,1,1); }
+}
- switch(info)
- {
- case 'Y': //year
+static long asfreq_AtoD(long fromDate, char relation) {
+ if (relation == 'B') { return absdate_from_ymd(fromDate,1,1); }
+ else { return absdate_from_ymd(fromDate+1,1,1) - 1; }
+}
- return (long)(convDate->year);
+static long asfreq_AtoH(long fromDate, char relation) { return 0; }
+static long asfreq_AtoT(long fromDate, char relation) { return 0; }
+static long asfreq_AtoS(long fromDate, char relation) { return 0; }
- case 'Q': //quarter
- monthNum = (long)(convDate->month);
- return ((monthNum-1)/3)+1;
- case 'M': //month
- return (long)(convDate->month);
+//************ FROM QUARTERLY ***************
- case 'D': //day
- return (long)(convDate->day);
+static long asfreq_QtoA(long fromDate, char relation) { return (fromDate - 1) / 4; }
- case 'W': //day of week
- return (long)(convDate->day_of_week);
- default:
- return -1;
+static long asfreq_QtoM(long fromDate, char relation) {
+ if (relation == 'B') { return fromDate * 3 - 2; }
+ else { return fromDate * 3; }
+}
+
+static long asfreq_QtoW(long fromDate, char relation) { return 0; }
+
+static void QtoD_ym(long fromDate, long *y, long *m) {
+ *y = (fromDate - 1) / 4;
+ *m = fromDate * 3 - 12 * (*y) - 2;
+}
+
+static long asfreq_QtoB(long fromDate, char relation) {
+
+ long y, m;
+
+ if (relation == 'B') {
+ QtoD_ym(fromDate, &y, &m);
+ return busday_before(y,m,1);
+ } else {
+ QtoD_ym(fromDate+1, &y, &m);
+ return busday_after(y, m, 1);
}
}
+static long asfreq_QtoD(long fromDate, char relation) {
-static char cseries_getDateInfo_doc[] = "";
-static PyObject *
-cseries_getDateInfo(PyObject *self, PyObject *args)
-{
- char *freq;
- char *info;
+ long y, m;
- PyArrayObject *array;
- PyArrayObject *tempArray;
- PyArrayObject *newArray;
+ if (relation == 'B') {
+ QtoD_ym(fromDate, &y, &m);
+ return absdate_from_ymd(y, m, 1);
+ } else {
+ QtoD_ym(fromDate+1, &y, &m);
+ return absdate_from_ymd(y, m, 1) - 1;
+ }
+}
- char *getptr;
- PyObject *val;
- long i, lngVal, dInfo, dim;
+static long asfreq_QtoH(long fromDate, char relation) { return 0; }
+static long asfreq_QtoT(long fromDate, char relation) { return 0; }
+static long asfreq_QtoS(long fromDate, char relation) { return 0; }
- if (!PyArg_ParseTuple(args, "Oss:getDateInfo(array, freq, info)", &tempArray, &freq, &info)) return NULL;
- array = PyArray_GETCONTIGUOUS(tempArray);
+//************ FROM MONTHLY ***************
- dim = array->dimensions[0];
+static long asfreq_MtoA(long fromDate, char relation) { return (fromDate - 1) / 12; }
+static long asfreq_MtoQ(long fromDate, char relation) { return (fromDate - 1) / 3 + 1; }
- //initialize new array
- newArray = (PyArrayObject*)PyArray_SimpleNew(array->nd, &dim, array->descr->type_num);
+static long asfreq_MtoW(long fromDate, char relation) { return 0; }
- for (i = 0; i < array->dimensions[0]; i++)
- {
- getptr = array->data + i*array->strides[0];
- val = PyArray_GETITEM(array, getptr);
- lngVal = PyInt_AsLong(val);
- dInfo = getDateInfo_sub(lngVal, *freq, *info);
+static void MtoD_ym(long fromDate, long *y, long *m) {
+ *y = (fromDate - 1) / 12;
+ *m = fromDate - 12 * (*y);
+}
- setArrayItem_1D(&newArray, i, PyInt_FromLong(dInfo));
+static long asfreq_MtoB(long fromDate, char relation) {
+
+ long y, m;
+
+ if (relation == 'B') {
+ MtoD_ym(fromDate, &y, &m);
+ return busday_before(y,m,1);
+ } else {
+ MtoD_ym(fromDate+1, &y, &m);
+ return busday_after(y, m, 1);
}
+}
- return (PyObject *) newArray;
+static long asfreq_MtoD(long fromDate, char relation) {
+ long y, m;
+
+ if (relation == 'B') {
+ MtoD_ym(fromDate, &y, &m);
+ return absdate_from_ymd(y, m, 1);
+ } else {
+ MtoD_ym(fromDate+1, &y, &m);
+ return absdate_from_ymd(y, m, 1) - 1;
+ }
}
+static long asfreq_MtoH(long fromDate, char relation) { return 0; }
+static long asfreq_MtoT(long fromDate, char relation) { return 0; }
+static long asfreq_MtoS(long fromDate, char relation) { return 0; }
-/*
-convert fromDate to a date at toFreq according to relation
-*/
-static long
-asfreq(long fromDate, char fromFreq, char toFreq, char relation)
-{
- long absdate, secsInDay;
- long converted;
- int y,m, doAfter;
- mxDateTimeObject *convDate;
+//************ FROM WEEKLY ***************
- secsInDay = 86400;
- doAfter = 0;
+static long asfreq_WtoA(long fromDate, char relation) { return 0; }
+static long asfreq_WtoQ(long fromDate, char relation) { return 0; }
+static long asfreq_WtoM(long fromDate, char relation) { return 0; }
+static long asfreq_WtoB(long fromDate, char relation) { return 0; }
+static long asfreq_WtoD(long fromDate, char relation) { return 0; }
+static long asfreq_WtoH(long fromDate, char relation) { return 0; }
+static long asfreq_WtoT(long fromDate, char relation) { return 0; }
+static long asfreq_WtoS(long fromDate, char relation) { return 0; }
- if (relation == 'A') {
- switch(fromFreq)
- {
- case 'D': //daily
+//************ FROM DAILY ***************
- switch(toFreq)
- {
- case 'A':
- break;
- case 'Q':
- break;
- case 'M':
- break;
- case 'B':
- break;
- default:
- doAfter = 1;
- break;
- }
- break;
+static long asfreq_DtoA(long fromDate, char relation) {
+ mxDateTimeObject *mxDate;
+ long result;
- case 'B': //business
+ mxDate = (mxDateTimeObject *)mxDateTime.DateTime_FromAbsDateAndTime(fromDate, 0);
+ result = (long)(mxDate->year);
+ Py_DECREF(mxDate);
+ return result;
+}
- switch(toFreq)
- {
- case 'A':
- break;
- case 'Q':
- break;
- case 'M':
- break;
- case 'D':
- break;
- default:
- doAfter = 1;
- break;
- }
- break;
+static long asfreq_DtoQ(long fromDate, char relation) {
- case 'M': //monthly
+ mxDateTimeObject *mxDate;
+ long result;
- switch(toFreq)
- {
- case 'A':
- break;
- case 'Q':
- break;
- default:
- doAfter = 1;
- break;
- }
- break;
+ mxDate = (mxDateTimeObject *)mxDateTime.DateTime_FromAbsDateAndTime(fromDate, 0);
+ result = (long)((mxDate->year) * 4 + (mxDate->month-1)/3 + 1);
+ Py_DECREF(mxDate);
+ return result;
+}
- case 'Q': //quarterly
+static long asfreq_DtoM(long fromDate, char relation) {
+ mxDateTimeObject *mxDate;
+ long result;
- switch(toFreq)
- {
- case 'A':
- break;
- default:
- doAfter = 1;
- break;
- }
- break;
+ mxDate = (mxDateTimeObject *)mxDateTime.DateTime_FromAbsDateAndTime(fromDate, 0);
+ result = (long)((mxDate->year) * 12 + mxDate->month);
+ Py_DECREF(mxDate);
+ return result;
+}
- case 'A': //annual
- doAfter = 1;
- break;
- }
+static long asfreq_DtoW(long fromDate, char relation) { return 0; }
- }
+static long asfreq_DtoB(long fromDate, char relation) {
+ mxDateTimeObject *mxDate;
+ long result;
- if (doAfter) {
- absdate = toDaily(fromDate + 1, fromFreq);
+ mxDate = (mxDateTimeObject *)mxDateTime.DateTime_FromAbsDateAndTime(fromDate, 0);
+ if (relation == 'B') {
+ result = DtoB_WeekendToFriday(mxDate);
} else {
- absdate = toDaily(fromDate, fromFreq);
+ result = DtoB_WeekendToMonday(mxDate);
}
- convDate = (mxDateTimeObject *)mxDateTime.DateTime_FromAbsDateAndTime(absdate,0);
+ Py_DECREF(mxDate);
+ return result;
+}
- y = convDate->year;
- m = convDate->month;
+static long asfreq_DtoB_forConvert(long fromDate, char relation) {
+ mxDateTimeObject *mxDate;
+ long result;
- //convert convDate to appropriate # of periods according to toFreq
- switch(toFreq)
- {
- case 'D':
- converted = absdate;
- break;
- case 'B':
- if (convDate->day_of_week > 4) //is weekend day
- {
- if (fromFreq == 'D' && relation == 'B') {
- //change to friday before weekend
- absdate -= (convDate->day_of_week - 4);
- } else {
- //change to Monday after weekend
- absdate += (7 - convDate->day_of_week);
- }
- }
- //converted = (long)((absdate / 7 * 5.0) + absdate%7);
- converted = (long)((absdate / 7 * 5.0) + absdate%7);
- break;
- case 'M':
- converted = (long)(y*12 + m);
- break;
- case 'Q':
- converted = (long)(y*4 + ((m-1)/3) + 1);
- break;
- case 'A':
- converted = (long)(y);
- break;
- default:
- return -1;
- }
+ mxDate = (mxDateTimeObject *)mxDateTime.DateTime_FromAbsDateAndTime(fromDate, 0);
- if (doAfter) {
- return converted-1;
+ if (mxDate->day_of_week > 4) {
+ result = -1;
} else {
- return converted;
+ result = DtoB_weekday(mxDate->absdate);
}
+
+ Py_DECREF(mxDate);
+ return result;
}
-/*
-for use internally by the convert function. Same as the asfreq function,
-except going from daily to business returns -1 always if fromDate is on
-a weekend
-*/
-static long
-asfreq_forseries(long fromDate, char fromFreq, char toFreq, char relation)
-{
- mxDateTimeObject *convDate;
+static long asfreq_DtoH(long fromDate, char relation) { return 0; }
+static long asfreq_DtoT(long fromDate, char relation) { return 0; }
+static long asfreq_DtoS(long fromDate, char relation) { return 0; }
- if (fromFreq == 'D' && toFreq == 'B') {
- convDate = (mxDateTimeObject *)mxDateTime.DateTime_FromAbsDateAndTime(fromDate,0);
- if (convDate->day_of_week > 4) //is weekend day
- {
- return -1;
- }
- }
+//************ FROM BUSINESS ***************
- return asfreq(fromDate, fromFreq, toFreq, relation);
-}
+static long asfreq_BtoD(long fromDate, char relation) {
+ return ((fromDate-1)/5)*7 + (fromDate-1)%5 + 1; }
-static int validFreq(char freq) {
- switch(freq)
+static long asfreq_BtoA(long fromDate, char relation) {
+ return asfreq_DtoA(asfreq_BtoD(fromDate, relation), relation); }
+
+static long asfreq_BtoQ(long fromDate, char relation) {
+ return asfreq_DtoQ(asfreq_BtoD(fromDate, relation), relation); }
+
+static long asfreq_BtoM(long fromDate, char relation) {
+ return asfreq_DtoM(asfreq_BtoD(fromDate, relation), relation); }
+
+static long asfreq_BtoW(long fromDate, char relation) {
+ return asfreq_DtoW(asfreq_BtoD(fromDate, relation), relation); }
+
+static long asfreq_BtoH(long fromDate, char relation) {
+ return asfreq_DtoH(asfreq_BtoD(fromDate, relation), relation); }
+
+static long asfreq_BtoT(long fromDate, char relation) {
+ return asfreq_DtoT(asfreq_BtoD(fromDate, relation), relation); }
+
+static long asfreq_BtoS(long fromDate, char relation) {
+ return asfreq_DtoS(asfreq_BtoD(fromDate, relation), relation); }
+
+//************ FROM HOURLY ***************
+
+static long asfreq_HtoA(long fromDate, char relation) { return 0; }
+static long asfreq_HtoQ(long fromDate, char relation) { return 0; }
+static long asfreq_HtoM(long fromDate, char relation) { return 0; }
+static long asfreq_HtoW(long fromDate, char relation) { return 0; }
+static long asfreq_HtoB(long fromDate, char relation) { return 0; }
+static long asfreq_HtoB_forConvert(long fromDate, char relation) { return 0; }
+static long asfreq_HtoD(long fromDate, char relation) { return 0; }
+static long asfreq_HtoT(long fromDate, char relation) { return 0; }
+static long asfreq_HtoS(long fromDate, char relation) { return 0; }
+
+//************ FROM MINUTELY ***************
+
+static long asfreq_TtoA(long fromDate, char relation) { return 0; }
+static long asfreq_TtoQ(long fromDate, char relation) { return 0; }
+static long asfreq_TtoM(long fromDate, char relation) { return 0; }
+static long asfreq_TtoW(long fromDate, char relation) { return 0; }
+static long asfreq_TtoB(long fromDate, char relation) { return 0; }
+static long asfreq_TtoB_forConvert(long fromDate, char relation) { return 0; }
+static long asfreq_TtoD(long fromDate, char relation) { return 0; }
+static long asfreq_TtoH(long fromDate, char relation) { return 0; }
+static long asfreq_TtoS(long fromDate, char relation) { return 0; }
+
+//************ FROM SECONDLY ***************
+
+static long asfreq_StoA(long fromDate, char relation) { return 0; }
+static long asfreq_StoQ(long fromDate, char relation) { return 0; }
+static long asfreq_StoM(long fromDate, char relation) { return 0; }
+static long asfreq_StoW(long fromDate, char relation) { return 0; }
+static long asfreq_StoB(long fromDate, char relation) { return 0; }
+static long asfreq_StoB_forConvert(long fromDate, char relation) { return 0; }
+static long asfreq_StoD(long fromDate, char relation) { return 0; }
+static long asfreq_StoH(long fromDate, char relation) { return 0; }
+static long asfreq_StoT(long fromDate, char relation) { return 0; }
+
+static long nofunc(long fromDate, char relation) { return -1; }
+
+// end of frequency specific conversion routines
+
+// return a pointer to appropriate conversion function
+static long (*get_asfreq_func(char fromFreq, char toFreq, int forConvert))(long, char) {
+
+ switch(fromFreq)
{
case 'A':
- return 1;
+ switch(toFreq)
+ {
+ case 'Q': return &asfreq_AtoQ;
+ case 'M': return &asfreq_AtoM;
+ case 'W': return &asfreq_AtoW;
+ case 'B': return &asfreq_AtoB;
+ case 'D': return &asfreq_AtoD;
+ case 'H': return &asfreq_AtoH;
+ case 'T': return &asfreq_AtoT;
+ case 'S': return &asfreq_AtoS;
+ default: return &nofunc;
+ }
+
case 'Q':
- return 1;
+ switch(toFreq)
+ {
+ case 'A': return &asfreq_QtoA;
+ case 'M': return &asfreq_QtoM;
+ case 'W': return &asfreq_QtoW;
+ case 'B': return &asfreq_QtoB;
+ case 'D': return &asfreq_QtoD;
+ case 'H': return &asfreq_QtoH;
+ case 'T': return &asfreq_QtoT;
+ case 'S': return &asfreq_QtoS;
+ default: return &nofunc;
+ }
+
case 'M':
- return 1;
+ switch(toFreq)
+ {
+ case 'A': return &asfreq_MtoA;
+ case 'Q': return &asfreq_MtoQ;
+ case 'W': return &asfreq_MtoW;
+ case 'B': return &asfreq_MtoB;
+ case 'D': return &asfreq_MtoD;
+ case 'H': return &asfreq_MtoH;
+ case 'T': return &asfreq_MtoT;
+ case 'S': return &asfreq_MtoS;
+ default: return &nofunc;
+ }
+
+ case 'W':
+ switch(toFreq)
+ {
+ case 'A': return &asfreq_WtoA;
+ case 'Q': return &asfreq_WtoQ;
+ case 'M': return &asfreq_WtoM;
+ case 'B': return &asfreq_WtoB;
+ case 'D': return &asfreq_WtoD;
+ case 'H': return &asfreq_WtoH;
+ case 'T': return &asfreq_WtoT;
+ case 'S': return &asfreq_WtoS;
+ default: return &nofunc;
+ }
+
case 'B':
- return 1;
+ switch(toFreq)
+ {
+ case 'A': return &asfreq_BtoA;
+ case 'Q': return &asfreq_BtoQ;
+ case 'M': return &asfreq_BtoM;
+ case 'W': return &asfreq_BtoW;
+ case 'D': return &asfreq_BtoD;
+ case 'H': return &asfreq_BtoH;
+ case 'T': return &asfreq_BtoT;
+ case 'S': return &asfreq_BtoS;
+ default: return &nofunc;
+ }
+
case 'D':
- return 1;
- default:
- return 0;
+ switch(toFreq)
+ {
+ case 'A': return &asfreq_DtoA;
+ case 'Q': return &asfreq_DtoQ;
+ case 'M': return &asfreq_DtoM;
+ case 'W': return &asfreq_DtoW;
+ case 'B':
+ if (forConvert) { return &asfreq_DtoB_forConvert; }
+ else { return &asfreq_DtoB; }
+ case 'H': return &asfreq_DtoH;
+ case 'T': return &asfreq_DtoT;
+ case 'S': return &asfreq_DtoS;
+ default: return &nofunc;
+ }
+
+ case 'H':
+ switch(toFreq)
+ {
+ case 'A': return &asfreq_HtoA;
+ case 'Q': return &asfreq_HtoQ;
+ case 'M': return &asfreq_HtoM;
+ case 'W': return &asfreq_HtoW;
+ case 'B':
+ if (forConvert) { return &asfreq_HtoB_forConvert; }
+ else { return &asfreq_HtoB; }
+ case 'D': return &asfreq_HtoD;
+ case 'T': return &asfreq_HtoT;
+ case 'S': return &asfreq_HtoS;
+ default: return &nofunc;
+ }
+
+ case 'T':
+ switch(toFreq)
+ {
+ case 'A': return &asfreq_TtoA;
+ case 'Q': return &asfreq_TtoQ;
+ case 'M': return &asfreq_TtoM;
+ case 'W': return &asfreq_TtoW;
+ case 'B':
+ if (forConvert) { return &asfreq_TtoB_forConvert; }
+ else { return &asfreq_TtoB; }
+ case 'D': return &asfreq_TtoD;
+ case 'H': return &asfreq_TtoH;
+ case 'S': return &asfreq_TtoS;
+ default: return &nofunc;
+ }
+
+ case 'S':
+ switch(toFreq)
+ {
+ case 'A': return &asfreq_StoA;
+ case 'Q': return &asfreq_StoQ;
+ case 'M': return &asfreq_StoM;
+ case 'W': return &asfreq_StoW;
+ case 'B':
+ if (forConvert) { return &asfreq_StoB_forConvert; }
+ else { return &asfreq_StoB; }
+ case 'D': return &asfreq_StoD;
+ case 'H': return &asfreq_StoH;
+ case 'T': return &asfreq_StoT;
+ default: return &nofunc;
+ }
+ default: return &nofunc;
}
}
+static long dInfo_year(mxDateTimeObject *dateObj) { return dateObj->year; }
+static long dInfo_quarter(mxDateTimeObject *dateObj) { return ((dateObj->month-1)/3)+1; }
+static long dInfo_month(mxDateTimeObject *dateObj) { return dateObj->month; }
+static long dInfo_day(mxDateTimeObject *dateObj) { return dateObj->day; }
+static long dInfo_dow(mxDateTimeObject *dateObj) { return dateObj->day_of_week; }
-static int
-expand(long oldSize, char fromFreq, char toFreq, long *newLen, long *newHeight)
+static char cseries_getDateInfo_doc[] = "";
+static PyObject *
+cseries_getDateInfo(PyObject *self, PyObject *args)
{
+ char *freq;
+ char *info;
- int maxBusDaysPerYear, maxBusDaysPerQuarter, maxBusDaysPerMonth;
- int minBusDaysPerYear, minBusDaysPerQuarter, minBusDaysPerMonth;
+ PyArrayObject *array;
+ PyArrayObject *newArray;
+ PyArrayIterObject *iterSource, *iterResult;
+ mxDateTimeObject *convDate;
- int maxDaysPerYear, maxDaysPerQuarter, maxDaysPerMonth;
- int minDaysPerYear, minDaysPerQuarter, minDaysPerMonth;
+ PyObject *val;
+ long dateNum, dInfo;
- minBusDaysPerYear = 260; maxBusDaysPerYear = 262;
- minBusDaysPerQuarter = 64; maxBusDaysPerQuarter = 66;
- minBusDaysPerMonth = 20; maxBusDaysPerMonth = 23;
+ long (*toDaily)(long, char) = NULL;
+ long (*getDateInfo)(mxDateTimeObject*) = NULL;
- minDaysPerYear = 365; maxDaysPerYear = 366;
- minDaysPerQuarter = 90; maxDaysPerQuarter = 92;
- minDaysPerMonth = 28; maxDaysPerMonth = 31;
+ if (!PyArg_ParseTuple(args, "Oss:getDateInfo(array, freq, info)", &array, &freq, &info)) return NULL;
+ newArray = (PyArrayObject *)PyArray_Copy(array);
- if (!validFreq(fromFreq)) return 0;
- if (!validFreq(toFreq)) return 0;
+ iterSource = (PyArrayIterObject *)PyArray_IterNew((PyObject *)array);
+ iterResult = (PyArrayIterObject *)PyArray_IterNew((PyObject *)newArray);
- if (fromFreq == toFreq) {
- *newLen = oldSize;
- *newHeight = 1;
- } else {
+ toDaily = get_asfreq_func(*freq, 'D', 0);
- switch(fromFreq)
- {
- case 'A': //annual
+ switch(*info)
+ {
+ case 'Y': //year
+ getDateInfo = &dInfo_year;
+ break;
+ case 'Q': //quarter
+ getDateInfo = &dInfo_quarter;
+ break;
+ case 'M': //month
+ getDateInfo = &dInfo_month;
+ break;
+ case 'D': //day
+ getDateInfo = &dInfo_day;
+ break;
+ case 'W': //day of week
+ getDateInfo = &dInfo_dow;
+ break;
+ default:
+ return NULL;
+ }
- switch(toFreq)
- {
- case 'Q':
- *newLen = oldSize * 4;
- *newHeight = 1;
- break;
- case 'M':
- *newLen = oldSize * 12;
- *newHeight = 1;
- break;
- case 'B':
- *newLen = oldSize * maxBusDaysPerYear;
- *newHeight = 1;
- break;
- case 'D':
- *newLen = oldSize * maxDaysPerYear;
- *newHeight = 1;
- break;
- }
- break;
+ while (iterSource->index < iterSource->size) {
- case 'Q': //quarterly
+ val = PyArray_GETITEM(array, iterSource->dataptr);
+ dateNum = PyInt_AsLong(val);
- switch(toFreq)
- {
- case 'A':
- *newLen = (oldSize / 4) + 2;
- *newHeight = 4;
- break;
- case 'M':
- *newLen = oldSize * 3;
- *newHeight = 1;
- break;
- case 'B':
- *newLen = oldSize * maxBusDaysPerQuarter;
- *newHeight = 1;
- break;
- case 'D':
- *newLen = oldSize * maxDaysPerQuarter;
- *newHeight = 1;
- break;
- }
- break;
+ convDate = (mxDateTimeObject *)mxDateTime.DateTime_FromAbsDateAndTime(toDaily(dateNum, 'A'), 0);
+ dInfo = getDateInfo(convDate);
+ Py_DECREF(convDate);
- case 'M': //monthly
+ PyArray_SETITEM(newArray, iterResult->dataptr, PyInt_FromLong(dInfo));
- switch(toFreq)
- {
- case 'A':
- *newLen = (oldSize / 12) + 2;
- *newHeight = 12;
- break;
- case 'Q':
- *newLen = (oldSize / 3) + 2;
- *newHeight = 3;
- break;
- case 'B':
- *newLen = oldSize * maxBusDaysPerMonth;
- *newHeight = 1;
- break;
- case 'D':
- *newLen = oldSize * maxDaysPerMonth;
- *newHeight = 1;
- break;
- }
- break;
+ PyArray_ITER_NEXT(iterSource);
+ PyArray_ITER_NEXT(iterResult);
+ }
- case 'B': //business
+ Py_DECREF(iterSource);
+ Py_DECREF(iterResult);
- switch(toFreq)
- {
- case 'A':
- *newLen = (oldSize / minBusDaysPerYear) + 2;
- *newHeight = maxBusDaysPerYear;
- break;
- case 'Q':
- *newLen = (oldSize / minBusDaysPerQuarter) + 2;
- *newHeight = maxBusDaysPerQuarter;
- break;
- case 'M':
- *newLen = (oldSize / minBusDaysPerMonth) + 2;
- *newHeight = maxBusDaysPerMonth;
- break;
- case 'D':
- *newLen = ((7 * oldSize)/5) + 2;
- *newHeight = 1;
- break;
- }
- break;
+ return (PyObject *) newArray;
- case 'D': //daily
+}
- switch(toFreq)
- {
- case 'A':
- *newLen = (oldSize / minDaysPerYear) + 2;
- *newHeight = maxDaysPerYear;
- break;
- case 'Q':
- *newLen = (oldSize / minDaysPerQuarter) + 2;
- *newHeight = maxDaysPerQuarter;
- break;
- case 'M':
- *newLen = (oldSize / minDaysPerMonth) + 2;
- *newHeight = maxDaysPerMonth;
- break;
- case 'B':
- *newLen = ((5 * oldSize)/7) + 2;
- *newHeight = 1;
- break; }
- break;
- }
- }
- return 1;
+static long get_height(char fromFreq, char toFreq) {
+ int maxBusDaysPerYear, maxBusDaysPerQuarter, maxBusDaysPerMonth;
+ int maxDaysPerYear, maxDaysPerQuarter, maxDaysPerMonth;
+
+ maxBusDaysPerYear = 262;
+ maxBusDaysPerQuarter = 66;
+ maxBusDaysPerMonth = 23;
+
+ maxDaysPerYear = 366;
+ maxDaysPerQuarter = 92;
+ maxDaysPerMonth = 31;
+
+ switch(fromFreq)
+ {
+ case 'A': return 1;
+ case 'Q':
+ switch(toFreq)
+ {
+ case 'A': return 4;
+ default: return 1;
+ }
+ case 'M': //monthly
+ switch(toFreq)
+ {
+ case 'A': return 12;
+ case 'Q': return 3;
+ default: return 1;
+ }
+ case 'B': //business
+ switch(toFreq)
+ {
+ case 'A': return maxBusDaysPerYear;;
+ case 'Q': return maxBusDaysPerQuarter;
+ case 'M': return maxBusDaysPerMonth;
+ case 'W': return 5;
+ default: return 1;
+ }
+ case 'D': //daily
+ switch(toFreq)
+ {
+ case 'A': return maxDaysPerYear;;
+ case 'Q': return maxDaysPerQuarter;
+ case 'M': return maxDaysPerMonth;
+ case 'W': return 7;
+ default: return 1;
+ }
+ default: return 1;
+ }
}
@@ -527,39 +626,37 @@
static PyObject *
cseries_convert(PyObject *self, PyObject *args)
{
- PyArrayObject *array;
- PyArrayObject *tempArray;
- PyArrayObject *newArray;
+ PyArrayObject *array, *newArray;
+ PyArrayObject *mask, *newMask;
- PyArrayObject *mask;
- PyArrayObject *tempMask;
- PyArrayObject *newMask;
-
PyObject *returnVal = NULL;
- long startIndex, newStart, newStartYaxis;
+ long startIndex;
+ long newStart, newStartTemp;
+ long newEnd, newEndTemp;
long newLen, newHeight;
long i, currIndex, prevIndex;
long nd;
- long *dim;
+ npy_intp *dim, *newIdx;
long currPerLen;
char *fromFreq, *toFreq, *position;
char relation;
PyObject *val, *valMask;
- int toFrVal, fromFrVal;
+ long (*asfreq_main)(long, char) = NULL;
+ long (*asfreq_endpoints)(long, char) = NULL;
+ long (*asfreq_reverse)(long, char) = NULL;
returnVal = PyDict_New();
- if (!PyArg_ParseTuple(args, "OssslO:convert(array, fromfreq, tofreq, position, startIndex, mask)", &tempArray, &fromFreq, &toFreq, &position, &startIndex, &tempMask)) return NULL;
+ if (!PyArg_ParseTuple(args, "OssslO:convert(array, fromfreq, tofreq, position, startIndex, mask)", &array, &fromFreq, &toFreq, &position, &startIndex, &mask)) return NULL;
if (toFreq[0] == fromFreq[0])
{
+ PyDict_SetItemString(returnVal, "values", (PyObject*)array);
+ PyDict_SetItemString(returnVal, "mask", (PyObject*)mask);
- PyDict_SetItemString(returnVal, "values", (PyObject*)tempArray);
- PyDict_SetItemString(returnVal, "mask", (PyObject*)tempMask);
-
return returnVal;
}
@@ -578,60 +675,57 @@
break;
}
- //get frequency numeric mapping
- fromFrVal = freqVal(fromFreq[0]);
- toFrVal = freqVal(toFreq[0]);
+ asfreq_main = get_asfreq_func(fromFreq[0], toFreq[0], 1);
+ asfreq_endpoints = get_asfreq_func(fromFreq[0], toFreq[0], 0);
- array = PyArray_GETCONTIGUOUS(tempArray);
- mask = PyArray_GETCONTIGUOUS(tempMask);
+ //convert start index to new frequency
+ newStartTemp = asfreq_main(startIndex, 'B');
+ if (newStartTemp == -1) { newStart = asfreq_endpoints(startIndex, 'A'); }
+ else { newStart = newStartTemp; }
- //expand size to fit new values if needed
- if (!expand(array->dimensions[0], fromFreq[0], toFreq[0], &newLen, &newHeight)) return NULL;
+ //convert end index to new frequency
+ newEndTemp = asfreq_main(startIndex+array->dimensions[0]-1, 'A');
+ if (newEndTemp == -1) { newEnd = asfreq_endpoints(startIndex, 'B'); }
+ else { newEnd = newEndTemp; }
- //convert start index to new frequency
- newStart = asfreq(startIndex, fromFreq[0], toFreq[0], 'B');
+ newLen = newEnd - newStart + 1;
+ newHeight = get_height(fromFreq[0], toFreq[0]);
if (newHeight > 1) {
- newStartYaxis = startIndex - asfreq(newStart, toFreq[0], fromFreq[0], 'B');
- currPerLen = newStartYaxis;
+ asfreq_reverse = get_asfreq_func(toFreq[0], fromFreq[0], 0);
+ currPerLen = startIndex - asfreq_reverse(newStart, 'B');
nd = 2;
- dim = malloc(nd * sizeof(int));
+ dim = PyDimMem_NEW(nd);
dim[0] = newLen;
dim[1] = newHeight;
} else {
- currPerLen = 0;
nd = 1;
- dim = malloc(nd * sizeof(int));
+ dim = PyDimMem_NEW(nd);
dim[0] = newLen;
}
+ newIdx = PyDimMem_NEW(nd);
newArray = (PyArrayObject*)PyArray_SimpleNew(nd, dim, array->descr->type_num);
newMask = (PyArrayObject*)PyArray_SimpleNew(nd, dim, mask->descr->type_num);
- free(dim);
+ PyDimMem_FREE(dim);
PyArray_FILLWBYTE(newArray,0);
PyArray_FILLWBYTE(newMask,1);
- //initialize prevIndex
prevIndex = newStart;
//set values in the new array
- for (i = 0; i < array->dimensions[0]; i++)
- {
+ for (i = 0; i < array->dimensions[0]; i++) {
- //get value from old array
val = PyArray_GETITEM(array, PyArray_GetPtr(array, &i));
-
- //get the mask corresponding to the old value
valMask = PyArray_GETITEM(mask, PyArray_GetPtr(mask, &i));
- //find index for start of current period in new frequency
- currIndex = asfreq_forseries(startIndex + i, fromFreq[0], toFreq[0], relation);
+ currIndex = asfreq_main(startIndex + i, relation);
+ newIdx[0] = currIndex-newStart;
-
if (newHeight > 1) {
if (currIndex != prevIndex)
@@ -641,23 +735,24 @@
prevIndex = currIndex;
}
- //set value in the new array
- setArrayItem_2D(&newArray, currIndex-newStart, currPerLen, val);
- setArrayItem_2D(&newMask, currIndex-newStart, currPerLen, valMask);
-
+ newIdx[1] = currPerLen;
currPerLen++;
+ }
- } else {
-
- setArrayItem_1D(&newArray, currIndex-newStart, val);
- setArrayItem_1D(&newMask, currIndex-newStart, valMask);
-
+ if (newIdx[0] > -1) {
+ PyArray_SETITEM(newArray, PyArray_GetPtr(newArray, newIdx), val);
+ PyArray_SETITEM(newMask, PyArray_GetPtr(newMask, newIdx), valMask);
}
+ Py_DECREF(val);
+ Py_DECREF(valMask);
}
+ PyDimMem_FREE(newIdx);
+
PyDict_SetItemString(returnVal, "values", (PyObject*)newArray);
PyDict_SetItemString(returnVal, "mask", (PyObject*)newMask);
+ PyDict_SetItemString(returnVal, "startindex", (PyObject*)PyInt_FromLong(newStart));
return returnVal;
@@ -673,9 +768,12 @@
PyObject *fromDateObj, *toDateObj;
char *fromFreq, *toFreq, *relation;
long fromDate, toDate;
+ long (*asfreq_main)(long, char) = NULL;
if (!PyArg_ParseTuple(args, "Osss:asfreq(fromDates, fromfreq, tofreq, relation)", &fromDates, &fromFreq, &toFreq, &relation)) return NULL;
+ asfreq_main = get_asfreq_func(fromFreq[0], toFreq[0], 0);
+
toDates = (PyArrayObject *)PyArray_Copy(fromDates);
iterFrom = (PyArrayIterObject *)PyArray_IterNew((PyObject *)fromDates);
@@ -688,15 +786,21 @@
fromDateObj = PyArray_GETITEM(fromDates, iterFrom->dataptr);
fromDate = PyInt_AsLong(fromDateObj);
- toDate = asfreq(fromDate, fromFreq[0], toFreq[0], relation[0]);
+ toDate = asfreq_main(fromDate, relation[0]);
toDateObj = PyInt_FromLong(toDate);
PyArray_SETITEM(toDates, iterTo->dataptr, toDateObj);
+ Py_DECREF(fromDateObj);
+ Py_DECREF(toDateObj);
+
PyArray_ITER_NEXT(iterFrom);
PyArray_ITER_NEXT(iterTo);
}
+ Py_DECREF(iterFrom);
+ Py_DECREF(iterTo);
+
return (PyObject *)toDates;
}
More information about the Scipy-svn
mailing list