1313 * Code derived from scikits.timeseries
1414 * ------------------------------------------------------------------*/
1515
16-
1716static int mod_compat (int x , int m ) {
1817 int result = x % m ;
1918 if (result < 0 ) return result + m ;
@@ -285,19 +284,19 @@ static int daytime_conversion_factors[][2] = {
285284
286285static npy_int64 * * daytime_conversion_factor_matrix = NULL ;
287286
288- static int max_value (int a , int b ) {
287+ PANDAS_INLINE static int max_value (int a , int b ) {
289288 return a > b ? a : b ;
290289}
291290
292- static int min_value (int a , int b ) {
291+ PANDAS_INLINE static int min_value (int a , int b ) {
293292 return a < b ? a : b ;
294293}
295294
296- static int get_freq_group (int freq ) {
295+ PANDAS_INLINE static int get_freq_group (int freq ) {
297296 return (freq /1000 )* 1000 ;
298297}
299298
300- static int get_freq_group_index (int freq ) {
299+ PANDAS_INLINE static int get_freq_group_index (int freq ) {
301300 return freq /1000 ;
302301}
303302
@@ -374,56 +373,39 @@ static void populate_conversion_factors_matrix() {
374373 }
375374}
376375
377- static void initialize_daytime_conversion_factor_maxtrix () {
378- int matrix_size = calc_conversion_factors_matrix_size ();
379- alloc_conversion_factors_matrix (matrix_size );
380- populate_conversion_factors_matrix ();
381- }
382-
383- npy_int64 get_daytime_conversion_factor (int index1 , int index2 )
384- {
376+ void initialize_daytime_conversion_factor_matrix () {
385377 if (daytime_conversion_factor_matrix == NULL ) {
386- initialize_daytime_conversion_factor_maxtrix ();
378+ int matrix_size = calc_conversion_factors_matrix_size ();
379+ alloc_conversion_factors_matrix (matrix_size );
380+ populate_conversion_factors_matrix ();
387381 }
388- return daytime_conversion_factor_matrix [min_value (index1 , index2 )][max_value (index1 , index2 )];
389382}
390383
391- npy_int64 convert_daytime ( npy_int64 ordinal , int from , int to , int atEnd )
384+ PANDAS_INLINE npy_int64 get_daytime_conversion_factor ( int from_index , int to_index )
392385{
393- int from_index , to_index , offset ;
394- npy_int64 conversion_factor ;
395-
396- if (from == to ) {
397- return ordinal ;
398- }
399-
400- from_index = get_freq_group_index (from );
401- to_index = get_freq_group_index (to );
402-
403- conversion_factor = get_daytime_conversion_factor (from_index , to_index );
404-
405- offset = atEnd ? 1 : 0 ;
386+ return daytime_conversion_factor_matrix [min_value (from_index , to_index )][max_value (from_index , to_index )];
387+ }
406388
407- if (from <= to ) {
408- return (ordinal + offset ) * conversion_factor - offset ;
389+ PANDAS_INLINE npy_int64 upsample_daytime (npy_int64 ordinal , asfreq_info * af_info , int atEnd )
390+ {
391+ if (atEnd ) {
392+ return (ordinal + 1 ) * af_info -> intraday_conversion_factor - 1 ;
409393 } else {
410- return ordinal / conversion_factor ;
394+ return ordinal * af_info -> intraday_conversion_factor ;
411395 }
412-
413396}
414397
415- static npy_int64 transform_via_day (npy_int64 ordinal , char relation , asfreq_info * af_info , freq_conv_func first_func , freq_conv_func second_func ) {
416- int tempStore = af_info -> targetFreq ;
398+ PANDAS_INLINE npy_int64 downsample_daytime (npy_int64 ordinal , asfreq_info * af_info , int atEnd )
399+ {
400+ return ordinal / (af_info -> intraday_conversion_factor );
401+ }
402+
403+ PANDAS_INLINE static npy_int64 transform_via_day (npy_int64 ordinal , char relation , asfreq_info * af_info , freq_conv_func first_func , freq_conv_func second_func ) {
404+ //printf("transform_via_day(%ld, %ld, %d)\n", ordinal, af_info->intraday_conversion_factor, af_info->intraday_conversion_upsample);
417405 npy_int64 result ;
418406
419- af_info -> targetFreq = FR_DAY ;
420407 result = (* first_func )(ordinal , relation , af_info );
421- af_info -> targetFreq = tempStore ;
422-
423- tempStore = af_info -> sourceFreq ;
424- af_info -> sourceFreq = FR_DAY ;
425408 result = (* second_func )(result , relation , af_info );
426- af_info -> sourceFreq = tempStore ;
427409
428410 return result ;
429411}
@@ -460,7 +442,7 @@ static npy_int64 absdate_from_ymd(int y, int m, int d) {
460442
461443static npy_int64 asfreq_DTtoA (npy_int64 ordinal , char relation , asfreq_info * af_info ) {
462444 struct date_info dinfo ;
463- ordinal = convert_daytime (ordinal , af_info -> sourceFreq , FR_DAY , 0 );
445+ ordinal = downsample_daytime (ordinal , af_info , 0 );
464446 if (dInfoCalc_SetFromAbsDate (& dinfo , ordinal + ORD_OFFSET , GREGORIAN_CALENDAR ))
465447 return INT_ERR_CODE ;
466448 if (dinfo .month > af_info -> to_a_year_end ) {
@@ -491,7 +473,7 @@ static npy_int64 DtoQ_yq(npy_int64 ordinal, asfreq_info *af_info, int *year, int
491473static npy_int64 asfreq_DTtoQ (npy_int64 ordinal , char relation , asfreq_info * af_info ) {
492474 int year , quarter ;
493475
494- ordinal = convert_daytime (ordinal , af_info -> sourceFreq , FR_DAY , 0 );
476+ ordinal = downsample_daytime (ordinal , af_info , 0 );
495477
496478 if (DtoQ_yq (ordinal , af_info , & year , & quarter ) == INT_ERR_CODE ) {
497479 return INT_ERR_CODE ;
@@ -503,22 +485,22 @@ static npy_int64 asfreq_DTtoQ(npy_int64 ordinal, char relation, asfreq_info *af_
503485static npy_int64 asfreq_DTtoM (npy_int64 ordinal , char relation , asfreq_info * af_info ) {
504486 struct date_info dinfo ;
505487
506- ordinal = convert_daytime (ordinal , af_info -> sourceFreq , FR_DAY , 0 );
488+ ordinal = downsample_daytime (ordinal , af_info , 0 );
507489
508490 if (dInfoCalc_SetFromAbsDate (& dinfo , ordinal + ORD_OFFSET , GREGORIAN_CALENDAR ))
509491 return INT_ERR_CODE ;
510492 return (npy_int64 )((dinfo .year - BASE_YEAR ) * 12 + dinfo .month - 1 );
511493}
512494
513495static npy_int64 asfreq_DTtoW (npy_int64 ordinal , char relation , asfreq_info * af_info ) {
514- ordinal = convert_daytime (ordinal , af_info -> sourceFreq , FR_DAY , 0 );
496+ ordinal = downsample_daytime (ordinal , af_info , 0 );
515497 return (ordinal + ORD_OFFSET - (1 + af_info -> to_week_end ))/7 + 1 - WEEK_OFFSET ;
516498}
517499
518500static npy_int64 asfreq_DTtoB (npy_int64 ordinal , char relation , asfreq_info * af_info ) {
519501 struct date_info dinfo ;
520502
521- ordinal = convert_daytime (ordinal , af_info -> sourceFreq , FR_DAY , 0 );
503+ ordinal = downsample_daytime (ordinal , af_info , 0 );
522504
523505 if (dInfoCalc_SetFromAbsDate (& dinfo , ordinal + ORD_OFFSET , GREGORIAN_CALENDAR ))
524506 return INT_ERR_CODE ;
@@ -531,14 +513,13 @@ static npy_int64 asfreq_DTtoB(npy_int64 ordinal, char relation, asfreq_info *af_
531513}
532514
533515// all intra day calculations are now done within one function
534- static npy_int64 asfreq_WithinDT (npy_int64 ordinal , char relation , asfreq_info * af_info ) {
535- //if (relation == 'E') {
536- // ordinal += 1;
537- //}
538-
539- return convert_daytime (ordinal , af_info -> sourceFreq , af_info -> targetFreq , relation == 'E' );
516+ static npy_int64 asfreq_DownsampleWithinDay (npy_int64 ordinal , char relation , asfreq_info * af_info ) {
517+ return downsample_daytime (ordinal , af_info , relation == 'E' );
540518}
541519
520+ static npy_int64 asfreq_UpsampleWithinDay (npy_int64 ordinal , char relation , asfreq_info * af_info ) {
521+ return upsample_daytime (ordinal , af_info , relation == 'E' );
522+ }
542523//************ FROM BUSINESS ***************
543524
544525static npy_int64 asfreq_BtoDT (npy_int64 ordinal , char relation , asfreq_info * af_info )
@@ -547,7 +528,7 @@ static npy_int64 asfreq_BtoDT(npy_int64 ordinal, char relation, asfreq_info *af_
547528 ordinal = (((ordinal - 1 ) / 5 ) * 7 +
548529 mod_compat (ordinal - 1 , 5 ) + 1 - ORD_OFFSET );
549530
550- return convert_daytime (ordinal , FR_DAY , af_info -> targetFreq , relation != 'S' );
531+ return upsample_daytime (ordinal , af_info , relation != 'S' );
551532}
552533
553534static npy_int64 asfreq_BtoA (npy_int64 ordinal , char relation , asfreq_info * af_info ) {
@@ -580,7 +561,7 @@ static npy_int64 asfreq_WtoDT(npy_int64 ordinal, char relation, asfreq_info *af_
580561 ordinal -= 1 ;
581562 }
582563
583- return convert_daytime (ordinal , FR_DAY , af_info -> targetFreq , relation != 'S' );
564+ return upsample_daytime (ordinal , af_info , relation != 'S' );
584565}
585566
586567static npy_int64 asfreq_WtoA (npy_int64 ordinal , char relation , asfreq_info * af_info ) {
@@ -602,12 +583,9 @@ static npy_int64 asfreq_WtoW(npy_int64 ordinal, char relation, asfreq_info *af_i
602583static npy_int64 asfreq_WtoB (npy_int64 ordinal , char relation , asfreq_info * af_info ) {
603584
604585 struct date_info dinfo ;
605- int tempStore = af_info -> targetFreq ;
606- af_info -> targetFreq = FR_DAY ;
607586 if (dInfoCalc_SetFromAbsDate (& dinfo ,
608587 asfreq_WtoDT (ordinal , relation , af_info ) + ORD_OFFSET ,
609588 GREGORIAN_CALENDAR )) return INT_ERR_CODE ;
610- af_info -> targetFreq = tempStore ;
611589
612590 if (relation == 'S' ) {
613591 return DtoB_WeekendToMonday (dinfo .absdate , dinfo .day_of_week );
@@ -639,7 +617,7 @@ static npy_int64 asfreq_MtoDT(npy_int64 ordinal, char relation, asfreq_info* af_
639617 ordinal -= 1 ;
640618 }
641619
642- return convert_daytime (ordinal , FR_DAY , af_info -> targetFreq , relation != 'S' );
620+ return upsample_daytime (ordinal , af_info , relation != 'S' );
643621}
644622
645623static npy_int64 asfreq_MtoA (npy_int64 ordinal , char relation , asfreq_info * af_info ) {
@@ -657,12 +635,9 @@ static npy_int64 asfreq_MtoW(npy_int64 ordinal, char relation, asfreq_info *af_i
657635static npy_int64 asfreq_MtoB (npy_int64 ordinal , char relation , asfreq_info * af_info ) {
658636 struct date_info dinfo ;
659637
660- int tempStore = af_info -> targetFreq ;
661- af_info -> targetFreq = FR_DAY ;
662638 if (dInfoCalc_SetFromAbsDate (& dinfo ,
663639 asfreq_MtoDT (ordinal , relation , af_info ) + ORD_OFFSET ,
664640 GREGORIAN_CALENDAR )) return INT_ERR_CODE ;
665- af_info -> targetFreq = tempStore ;
666641
667642 if (relation == 'S' ) { return DtoB_WeekendToMonday (dinfo .absdate , dinfo .day_of_week ); }
668643 else { return DtoB_WeekendToFriday (dinfo .absdate , dinfo .day_of_week ); }
@@ -698,7 +673,7 @@ static npy_int64 asfreq_QtoDT(npy_int64 ordinal, char relation, asfreq_info *af_
698673 absdate -= 1 ;
699674 }
700675
701- return convert_daytime (absdate - ORD_OFFSET , FR_DAY , af_info -> targetFreq , relation != 'S' );
676+ return upsample_daytime (absdate - ORD_OFFSET , af_info , relation != 'S' );
702677}
703678
704679static npy_int64 asfreq_QtoQ (npy_int64 ordinal , char relation , asfreq_info * af_info ) {
@@ -720,12 +695,9 @@ static npy_int64 asfreq_QtoW(npy_int64 ordinal, char relation, asfreq_info *af_i
720695static npy_int64 asfreq_QtoB (npy_int64 ordinal , char relation , asfreq_info * af_info ) {
721696
722697 struct date_info dinfo ;
723- int tempStore = af_info -> targetFreq ;
724- af_info -> targetFreq = FR_DAY ;
725698 if (dInfoCalc_SetFromAbsDate (& dinfo ,
726699 asfreq_QtoDT (ordinal , relation , af_info ) + ORD_OFFSET ,
727700 GREGORIAN_CALENDAR )) return INT_ERR_CODE ;
728- af_info -> targetFreq = tempStore ;
729701
730702 if (relation == 'S' ) { return DtoB_WeekendToMonday (dinfo .absdate , dinfo .day_of_week ); }
731703 else { return DtoB_WeekendToFriday (dinfo .absdate , dinfo .day_of_week ); }
@@ -761,7 +733,7 @@ static npy_int64 asfreq_AtoDT(npy_int64 year, char relation, asfreq_info *af_inf
761733 absdate -= 1 ;
762734 }
763735
764- return convert_daytime (absdate - ORD_OFFSET , FR_DAY , af_info -> targetFreq , relation != 'S' );
736+ return upsample_daytime (absdate - ORD_OFFSET , af_info , relation != 'S' );
765737}
766738
767739static npy_int64 asfreq_AtoA (npy_int64 ordinal , char relation , asfreq_info * af_info ) {
@@ -783,12 +755,9 @@ static npy_int64 asfreq_AtoW(npy_int64 ordinal, char relation, asfreq_info *af_i
783755static npy_int64 asfreq_AtoB (npy_int64 ordinal , char relation , asfreq_info * af_info ) {
784756
785757 struct date_info dinfo ;
786- int tempStore = af_info -> targetFreq ;
787- af_info -> targetFreq = FR_DAY ;
788758 if (dInfoCalc_SetFromAbsDate (& dinfo ,
789759 asfreq_AtoDT (ordinal , relation , af_info ) + ORD_OFFSET ,
790760 GREGORIAN_CALENDAR )) return INT_ERR_CODE ;
791- af_info -> targetFreq = tempStore ;
792761
793762 if (relation == 'S' ) { return DtoB_WeekendToMonday (dinfo .absdate , dinfo .day_of_week ); }
794763 else { return DtoB_WeekendToFriday (dinfo .absdate , dinfo .day_of_week ); }
@@ -813,8 +782,13 @@ void get_asfreq_info(int fromFreq, int toFreq, asfreq_info *af_info) {
813782 int fromGroup = get_freq_group (fromFreq );
814783 int toGroup = get_freq_group (toFreq );
815784
816- af_info -> sourceFreq = fromFreq ;
817- af_info -> targetFreq = toFreq ;
785+ af_info -> intraday_conversion_factor =
786+ get_daytime_conversion_factor (
787+ get_freq_group_index (max_value (fromGroup , FR_DAY )),
788+ get_freq_group_index (max_value (toGroup , FR_DAY ))
789+ );
790+
791+ //printf("get_asfreq_info(%d, %d) %ld, %d\n", fromFreq, toFreq, af_info->intraday_conversion_factor, af_info->intraday_conversion_upsample);
818792
819793 switch (fromGroup )
820794 {
@@ -970,7 +944,11 @@ freq_conv_func get_asfreq_func(int fromFreq, int toFreq)
970944 case FR_MS :
971945 case FR_US :
972946 case FR_NS :
973- return & asfreq_WithinDT ;
947+ if (fromGroup > toGroup ) {
948+ return & asfreq_DownsampleWithinDay ;
949+ } else {
950+ return & asfreq_UpsampleWithinDay ;
951+ }
974952 default : return & nofunc ;
975953 }
976954
@@ -1073,6 +1051,8 @@ npy_int64 asfreq(npy_int64 period_ordinal, int freq1, int freq2, char relation)
10731051
10741052 get_asfreq_info (freq1 , freq2 , & finfo );
10751053
1054+ //printf("\n%x %d %d %ld %ld\n", func, freq1, freq2, finfo.intraday_conversion_factor, -finfo.intraday_conversion_factor);
1055+
10761056 val = (* func )(period_ordinal , relation , & finfo );
10771057
10781058 if (val == INT_ERR_CODE ) {
0 commit comments