[Scipy-svn] r2486 - trunk/Lib/sandbox/timeseries/src
scipy-svn at scipy.org
scipy-svn at scipy.org
Thu Jan 4 11:08:16 EST 2007
Author: mattknox_ca
Date: 2007-01-04 10:08:13 -0600 (Thu, 04 Jan 2007)
New Revision: 2486
Modified:
trunk/Lib/sandbox/timeseries/src/cseries.c
Log:
revamped convert function so that it can act on an array of dates. Also, renamed some functions
Modified: trunk/Lib/sandbox/timeseries/src/cseries.c
===================================================================
--- trunk/Lib/sandbox/timeseries/src/cseries.c 2007-01-04 16:02:18 UTC (rev 2485)
+++ trunk/Lib/sandbox/timeseries/src/cseries.c 2007-01-04 16:08:13 UTC (rev 2486)
@@ -193,19 +193,101 @@
}
+/*
+convert fromDate to a date at toFreq according to relation
+*/
static long
-convert(long fromDate, char fromFreq, char toFreq, int notStartInd)
+asfreq(long fromDate, char fromFreq, char toFreq, char relation)
{
long absdate, secsInDay;
long converted;
- int y,m;
+ int y,m, doAfter;
mxDateTimeObject *convDate;
secsInDay = 86400;
+ doAfter = 0;
- absdate = toDaily(fromDate, fromFreq);
+ if (relation == 'A') {
+ switch(fromFreq)
+ {
+ case 'D': //daily
+
+ switch(toFreq)
+ {
+ case 'A':
+ break;
+ case 'Q':
+ break;
+ case 'M':
+ break;
+ case 'B':
+ break;
+ default:
+ doAfter = 1;
+ break;
+ }
+ break;
+
+ case 'B': //business
+
+ switch(toFreq)
+ {
+ case 'A':
+ break;
+ case 'Q':
+ break;
+ case 'M':
+ break;
+ case 'D':
+ break;
+ default:
+ doAfter = 1;
+ break;
+ }
+ break;
+
+ case 'M': //monthly
+
+ switch(toFreq)
+ {
+ case 'A':
+ break;
+ case 'Q':
+ break;
+ default:
+ doAfter = 1;
+ break;
+ }
+ break;
+
+ case 'Q': //quarterly
+
+ switch(toFreq)
+ {
+ case 'A':
+ break;
+ default:
+ doAfter = 1;
+ break;
+ }
+ break;
+
+ case 'A': //annual
+ doAfter = 1;
+ break;
+
+ }
+
+ }
+
+ if (doAfter) {
+ absdate = toDaily(fromDate + 1, fromFreq);
+ } else {
+ absdate = toDaily(fromDate, fromFreq);
+ }
+
convDate = (mxDateTimeObject *)mxDateTime.DateTime_FromAbsDateAndTime(absdate,0);
y = convDate->year;
@@ -220,27 +302,16 @@
case 'B':
if (convDate->day_of_week > 4) //is weekend day
{
- if (notStartInd == 1 && freqVal(fromFreq) > 4)
- {
- return -1;
+ 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);
}
- else
- {
- if (convDate->day - (convDate->day_of_week - 4) < 1) {
- //change to Monday after weekend
- absdate += (7 - convDate->day_of_week);
- } else {
- //change to friday before weekend
- absdate -= (convDate->day_of_week - 4);
- }
-
- converted = (long)((absdate / 7 * 5.0) + absdate%7);
- }
}
- else
- {
- converted = (long)((absdate / 7 * 5.0) + absdate%7);
- }
+ //converted = (long)((absdate / 7 * 5.0) + absdate%7);
+ converted = (long)((absdate / 7 * 5.0) + absdate%7);
break;
case 'M':
converted = (long)(y*12 + m);
@@ -255,9 +326,35 @@
return -1;
}
- return converted;
+ if (doAfter) {
+ return converted-1;
+ } else {
+ return converted;
+ }
}
+
+/*
+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;
+
+ if (fromFreq == 'D' && toFreq == 'B') {
+ convDate = (mxDateTimeObject *)mxDateTime.DateTime_FromAbsDateAndTime(fromDate,0);
+ if (convDate->day_of_week > 4) //is weekend day
+ {
+ return -1;
+ }
+ }
+
+ return asfreq(fromDate, fromFreq, toFreq, relation);
+}
+
static int validFreq(char freq) {
switch(freq)
{
@@ -426,9 +523,9 @@
}
-static char cseries_reindex_doc[] = "";
+static char cseries_convert_doc[] = "";
static PyObject *
-cseries_reindex(PyObject *self, PyObject *args)
+cseries_convert(PyObject *self, PyObject *args)
{
PyArrayObject *array;
PyArrayObject *tempArray;
@@ -440,7 +537,6 @@
PyObject *returnVal = NULL;
- int notStartInd;
long startIndex, newStart, newStartYaxis;
long newLen, newHeight;
long i, currIndex, prevIndex;
@@ -448,6 +544,7 @@
long *dim;
long currPerLen;
char *fromFreq, *toFreq, *position;
+ char relation;
PyObject *val, *valMask;
@@ -455,7 +552,7 @@
returnVal = PyDict_New();
- if (!PyArg_ParseTuple(args, "OssslO:reindex(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)", &tempArray, &fromFreq, &toFreq, &position, &startIndex, &tempMask)) return NULL;
if (toFreq[0] == fromFreq[0])
{
@@ -466,6 +563,21 @@
return returnVal;
}
+ switch(position[0])
+ {
+ case 'S':
+ // start -> before
+ relation = 'B';
+ break;
+ case 'E':
+ // end -> after
+ relation = 'A';
+ break;
+ default:
+ return NULL;
+ break;
+ }
+
//get frequency numeric mapping
fromFrVal = freqVal(fromFreq[0]);
toFrVal = freqVal(toFreq[0]);
@@ -477,12 +589,11 @@
if (!expand(array->dimensions[0], fromFreq[0], toFreq[0], &newLen, &newHeight)) return NULL;
//convert start index to new frequency
- notStartInd = 0;
- newStart = convert(startIndex, fromFreq[0], toFreq[0], notStartInd);
+ newStart = asfreq(startIndex, fromFreq[0], toFreq[0], 'B');
if (newHeight > 1) {
- newStartYaxis = startIndex - convert(newStart, toFreq[0], fromFreq[0], notStartInd);
+ newStartYaxis = startIndex - asfreq(newStart, toFreq[0], fromFreq[0], 'B');
currPerLen = newStartYaxis;
nd = 2;
@@ -507,8 +618,6 @@
//initialize prevIndex
prevIndex = newStart;
- notStartInd = 1;
-
//set values in the new array
for (i = 0; i < array->dimensions[0]; i++)
{
@@ -520,12 +629,9 @@
valMask = PyArray_GETITEM(mask, PyArray_GetPtr(mask, &i));
//find index for start of current period in new frequency
- if (newHeight == 1 && (position[0] == 'E' && !((fromFrVal == 4 && toFrVal == 5) || (fromFrVal == 5 && toFrVal == 4))) ) {
- currIndex = convert(startIndex + i + 1, fromFreq[0], toFreq[0], notStartInd)-1;
- } else {
- currIndex = convert(startIndex + i, fromFreq[0], toFreq[0], notStartInd);
- }
+ currIndex = asfreq_forseries(startIndex + i, fromFreq[0], toFreq[0], relation);
+
if (newHeight > 1) {
if (currIndex != prevIndex)
@@ -558,29 +664,49 @@
}
-static char cseries_convert_doc[] = "";
+static char cseries_asfreq_doc[] = "";
static PyObject *
-cseries_convert(PyObject *self, PyObject *args)
+cseries_asfreq(PyObject *self, PyObject *args)
{
- long fromDate;
- char* fromFreq;
- char* toFreq;
- int notStartInd;
+ PyArrayObject *fromDates, *toDates;
+ PyArrayIterObject *iterFrom, *iterTo;
+ PyObject *fromDateObj, *toDateObj;
+ char *fromFreq, *toFreq, *relation;
+ long fromDate, toDate;
- if (!PyArg_ParseTuple(args, "lss:convert(fromDate, fromfreq, tofreq)", &fromDate, &fromFreq, &toFreq)) return NULL;
+ if (!PyArg_ParseTuple(args, "Osss:asfreq(fromDates, fromfreq, tofreq, relation)", &fromDates, &fromFreq, &toFreq, &relation)) return NULL;
- //always want start of period (only matters when converting from lower freq to higher freq ie. m -> d)
- notStartInd = 0;
+ toDates = (PyArrayObject *)PyArray_Copy(fromDates);
- return PyInt_FromLong(convert(fromDate, fromFreq[0], toFreq[0], notStartInd));
+ iterFrom = (PyArrayIterObject *)PyArray_IterNew((PyObject *)fromDates);
+ if (iterFrom == NULL) return NULL;
+
+ iterTo = (PyArrayIterObject *)PyArray_IterNew((PyObject *)toDates);
+ if (iterTo == NULL) return NULL;
+
+ while (iterFrom->index < iterFrom->size) {
+
+ fromDateObj = PyArray_GETITEM(fromDates, iterFrom->dataptr);
+ fromDate = PyInt_AsLong(fromDateObj);
+ toDate = asfreq(fromDate, fromFreq[0], toFreq[0], relation[0]);
+ toDateObj = PyInt_FromLong(toDate);
+
+ PyArray_SETITEM(toDates, iterTo->dataptr, toDateObj);
+
+ PyArray_ITER_NEXT(iterFrom);
+ PyArray_ITER_NEXT(iterTo);
+ }
+
+ return (PyObject *)toDates;
+
}
///////////////////////////////////////////////////////////////////////
static PyMethodDef cseries_methods[] = {
- {"reindex", cseries_reindex, METH_VARARGS, cseries_reindex_doc},
{"convert", cseries_convert, METH_VARARGS, cseries_convert_doc},
+ {"asfreq", cseries_asfreq, METH_VARARGS, cseries_asfreq_doc},
{"getDateInfo", cseries_getDateInfo, METH_VARARGS, cseries_getDateInfo_doc},
{NULL, NULL}
};
More information about the Scipy-svn
mailing list