13
13
* Code derived from scikits.timeseries
14
14
* ------------------------------------------------------------------*/
15
15
16
-
17
16
static int mod_compat (int x , int m ) {
18
17
int result = x % m ;
19
18
if (result < 0 ) return result + m ;
@@ -285,19 +284,19 @@ static int daytime_conversion_factors[][2] = {
285
284
286
285
static npy_int64 * * daytime_conversion_factor_matrix = NULL ;
287
286
288
- static int max_value (int a , int b ) {
287
+ PANDAS_INLINE static int max_value (int a , int b ) {
289
288
return a > b ? a : b ;
290
289
}
291
290
292
- static int min_value (int a , int b ) {
291
+ PANDAS_INLINE static int min_value (int a , int b ) {
293
292
return a < b ? a : b ;
294
293
}
295
294
296
- static int get_freq_group (int freq ) {
295
+ PANDAS_INLINE static int get_freq_group (int freq ) {
297
296
return (freq /1000 )* 1000 ;
298
297
}
299
298
300
- static int get_freq_group_index (int freq ) {
299
+ PANDAS_INLINE static int get_freq_group_index (int freq ) {
301
300
return freq /1000 ;
302
301
}
303
302
@@ -374,56 +373,39 @@ static void populate_conversion_factors_matrix() {
374
373
}
375
374
}
376
375
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 () {
385
377
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 ();
387
381
}
388
- return daytime_conversion_factor_matrix [min_value (index1 , index2 )][max_value (index1 , index2 )];
389
382
}
390
383
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 )
392
385
{
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
+ }
406
388
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 ;
409
393
} else {
410
- return ordinal / conversion_factor ;
394
+ return ordinal * af_info -> intraday_conversion_factor ;
411
395
}
412
-
413
396
}
414
397
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);
417
405
npy_int64 result ;
418
406
419
- af_info -> targetFreq = FR_DAY ;
420
407
result = (* first_func )(ordinal , relation , af_info );
421
- af_info -> targetFreq = tempStore ;
422
-
423
- tempStore = af_info -> sourceFreq ;
424
- af_info -> sourceFreq = FR_DAY ;
425
408
result = (* second_func )(result , relation , af_info );
426
- af_info -> sourceFreq = tempStore ;
427
409
428
410
return result ;
429
411
}
@@ -460,7 +442,7 @@ static npy_int64 absdate_from_ymd(int y, int m, int d) {
460
442
461
443
static npy_int64 asfreq_DTtoA (npy_int64 ordinal , char relation , asfreq_info * af_info ) {
462
444
struct date_info dinfo ;
463
- ordinal = convert_daytime (ordinal , af_info -> sourceFreq , FR_DAY , 0 );
445
+ ordinal = downsample_daytime (ordinal , af_info , 0 );
464
446
if (dInfoCalc_SetFromAbsDate (& dinfo , ordinal + ORD_OFFSET , GREGORIAN_CALENDAR ))
465
447
return INT_ERR_CODE ;
466
448
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
491
473
static npy_int64 asfreq_DTtoQ (npy_int64 ordinal , char relation , asfreq_info * af_info ) {
492
474
int year , quarter ;
493
475
494
- ordinal = convert_daytime (ordinal , af_info -> sourceFreq , FR_DAY , 0 );
476
+ ordinal = downsample_daytime (ordinal , af_info , 0 );
495
477
496
478
if (DtoQ_yq (ordinal , af_info , & year , & quarter ) == INT_ERR_CODE ) {
497
479
return INT_ERR_CODE ;
@@ -503,22 +485,22 @@ static npy_int64 asfreq_DTtoQ(npy_int64 ordinal, char relation, asfreq_info *af_
503
485
static npy_int64 asfreq_DTtoM (npy_int64 ordinal , char relation , asfreq_info * af_info ) {
504
486
struct date_info dinfo ;
505
487
506
- ordinal = convert_daytime (ordinal , af_info -> sourceFreq , FR_DAY , 0 );
488
+ ordinal = downsample_daytime (ordinal , af_info , 0 );
507
489
508
490
if (dInfoCalc_SetFromAbsDate (& dinfo , ordinal + ORD_OFFSET , GREGORIAN_CALENDAR ))
509
491
return INT_ERR_CODE ;
510
492
return (npy_int64 )((dinfo .year - BASE_YEAR ) * 12 + dinfo .month - 1 );
511
493
}
512
494
513
495
static 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 );
515
497
return (ordinal + ORD_OFFSET - (1 + af_info -> to_week_end ))/7 + 1 - WEEK_OFFSET ;
516
498
}
517
499
518
500
static npy_int64 asfreq_DTtoB (npy_int64 ordinal , char relation , asfreq_info * af_info ) {
519
501
struct date_info dinfo ;
520
502
521
- ordinal = convert_daytime (ordinal , af_info -> sourceFreq , FR_DAY , 0 );
503
+ ordinal = downsample_daytime (ordinal , af_info , 0 );
522
504
523
505
if (dInfoCalc_SetFromAbsDate (& dinfo , ordinal + ORD_OFFSET , GREGORIAN_CALENDAR ))
524
506
return INT_ERR_CODE ;
@@ -531,14 +513,13 @@ static npy_int64 asfreq_DTtoB(npy_int64 ordinal, char relation, asfreq_info *af_
531
513
}
532
514
533
515
// 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' );
540
518
}
541
519
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
+ }
542
523
//************ FROM BUSINESS ***************
543
524
544
525
static 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_
547
528
ordinal = (((ordinal - 1 ) / 5 ) * 7 +
548
529
mod_compat (ordinal - 1 , 5 ) + 1 - ORD_OFFSET );
549
530
550
- return convert_daytime (ordinal , FR_DAY , af_info -> targetFreq , relation != 'S' );
531
+ return upsample_daytime (ordinal , af_info , relation != 'S' );
551
532
}
552
533
553
534
static 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_
580
561
ordinal -= 1 ;
581
562
}
582
563
583
- return convert_daytime (ordinal , FR_DAY , af_info -> targetFreq , relation != 'S' );
564
+ return upsample_daytime (ordinal , af_info , relation != 'S' );
584
565
}
585
566
586
567
static 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
602
583
static npy_int64 asfreq_WtoB (npy_int64 ordinal , char relation , asfreq_info * af_info ) {
603
584
604
585
struct date_info dinfo ;
605
- int tempStore = af_info -> targetFreq ;
606
- af_info -> targetFreq = FR_DAY ;
607
586
if (dInfoCalc_SetFromAbsDate (& dinfo ,
608
587
asfreq_WtoDT (ordinal , relation , af_info ) + ORD_OFFSET ,
609
588
GREGORIAN_CALENDAR )) return INT_ERR_CODE ;
610
- af_info -> targetFreq = tempStore ;
611
589
612
590
if (relation == 'S' ) {
613
591
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_
639
617
ordinal -= 1 ;
640
618
}
641
619
642
- return convert_daytime (ordinal , FR_DAY , af_info -> targetFreq , relation != 'S' );
620
+ return upsample_daytime (ordinal , af_info , relation != 'S' );
643
621
}
644
622
645
623
static 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
657
635
static npy_int64 asfreq_MtoB (npy_int64 ordinal , char relation , asfreq_info * af_info ) {
658
636
struct date_info dinfo ;
659
637
660
- int tempStore = af_info -> targetFreq ;
661
- af_info -> targetFreq = FR_DAY ;
662
638
if (dInfoCalc_SetFromAbsDate (& dinfo ,
663
639
asfreq_MtoDT (ordinal , relation , af_info ) + ORD_OFFSET ,
664
640
GREGORIAN_CALENDAR )) return INT_ERR_CODE ;
665
- af_info -> targetFreq = tempStore ;
666
641
667
642
if (relation == 'S' ) { return DtoB_WeekendToMonday (dinfo .absdate , dinfo .day_of_week ); }
668
643
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_
698
673
absdate -= 1 ;
699
674
}
700
675
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' );
702
677
}
703
678
704
679
static 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
720
695
static npy_int64 asfreq_QtoB (npy_int64 ordinal , char relation , asfreq_info * af_info ) {
721
696
722
697
struct date_info dinfo ;
723
- int tempStore = af_info -> targetFreq ;
724
- af_info -> targetFreq = FR_DAY ;
725
698
if (dInfoCalc_SetFromAbsDate (& dinfo ,
726
699
asfreq_QtoDT (ordinal , relation , af_info ) + ORD_OFFSET ,
727
700
GREGORIAN_CALENDAR )) return INT_ERR_CODE ;
728
- af_info -> targetFreq = tempStore ;
729
701
730
702
if (relation == 'S' ) { return DtoB_WeekendToMonday (dinfo .absdate , dinfo .day_of_week ); }
731
703
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
761
733
absdate -= 1 ;
762
734
}
763
735
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' );
765
737
}
766
738
767
739
static 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
783
755
static npy_int64 asfreq_AtoB (npy_int64 ordinal , char relation , asfreq_info * af_info ) {
784
756
785
757
struct date_info dinfo ;
786
- int tempStore = af_info -> targetFreq ;
787
- af_info -> targetFreq = FR_DAY ;
788
758
if (dInfoCalc_SetFromAbsDate (& dinfo ,
789
759
asfreq_AtoDT (ordinal , relation , af_info ) + ORD_OFFSET ,
790
760
GREGORIAN_CALENDAR )) return INT_ERR_CODE ;
791
- af_info -> targetFreq = tempStore ;
792
761
793
762
if (relation == 'S' ) { return DtoB_WeekendToMonday (dinfo .absdate , dinfo .day_of_week ); }
794
763
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) {
813
782
int fromGroup = get_freq_group (fromFreq );
814
783
int toGroup = get_freq_group (toFreq );
815
784
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);
818
792
819
793
switch (fromGroup )
820
794
{
@@ -970,7 +944,11 @@ freq_conv_func get_asfreq_func(int fromFreq, int toFreq)
970
944
case FR_MS :
971
945
case FR_US :
972
946
case FR_NS :
973
- return & asfreq_WithinDT ;
947
+ if (fromGroup > toGroup ) {
948
+ return & asfreq_DownsampleWithinDay ;
949
+ } else {
950
+ return & asfreq_UpsampleWithinDay ;
951
+ }
974
952
default : return & nofunc ;
975
953
}
976
954
@@ -1073,6 +1051,8 @@ npy_int64 asfreq(npy_int64 period_ordinal, int freq1, int freq2, char relation)
1073
1051
1074
1052
get_asfreq_info (freq1 , freq2 , & finfo );
1075
1053
1054
+ //printf("\n%x %d %d %ld %ld\n", func, freq1, freq2, finfo.intraday_conversion_factor, -finfo.intraday_conversion_factor);
1055
+
1076
1056
val = (* func )(period_ordinal , relation , & finfo );
1077
1057
1078
1058
if (val == INT_ERR_CODE ) {
0 commit comments