[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